diff --git a/src/ImageSharp.Drawing/Common/Extensions/GraphicsOptionsExtensions.cs b/src/ImageSharp.Drawing/Common/Extensions/GraphicsOptionsExtensions.cs
new file mode 100644
index 000000000..c32d0a46e
--- /dev/null
+++ b/src/ImageSharp.Drawing/Common/Extensions/GraphicsOptionsExtensions.cs
@@ -0,0 +1,53 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System.Numerics;
+using SixLabors.ImageSharp.PixelFormats;
+
+namespace SixLabors.ImageSharp
+{
+ ///
+ /// Extensions methods fpor the class.
+ ///
+ internal static class GraphicsOptionsExtensions
+ {
+ ///
+ /// Evaluates if a given SOURCE color can completely replace a BACKDROP color given the current blending and composition settings.
+ ///
+ /// The graphics options.
+ /// The source color.
+ /// true if the color can be considered opaque
+ ///
+ /// Blending and composition is an expensive operation, in some cases, like
+ /// filling with a solid color, the blending can be avoided by a plain color replacement.
+ /// This method can be useful for such processors to select the fast path.
+ ///
+ public static bool IsOpaqueColorWithoutBlending(this GraphicsOptions options, Color color)
+ {
+ if (options.ColorBlendingMode != PixelColorBlendingMode.Normal)
+ {
+ return false;
+ }
+
+ if (options.AlphaCompositionMode != PixelAlphaCompositionMode.SrcOver
+ && options.AlphaCompositionMode != PixelAlphaCompositionMode.Src)
+ {
+ return false;
+ }
+
+ const float Opaque = 1F;
+
+ if (options.BlendPercentage != Opaque)
+ {
+ return false;
+ }
+
+ if (((Vector4)color).W != Opaque)
+ {
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/ImageSharp.Drawing/Primitives/ShapeRegion.cs b/src/ImageSharp.Drawing/Primitives/ShapeRegion.cs
index f4a645820..c008f4419 100644
--- a/src/ImageSharp.Drawing/Primitives/ShapeRegion.cs
+++ b/src/ImageSharp.Drawing/Primitives/ShapeRegion.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.Primitives
using (IMemoryOwner tempBuffer = configuration.MemoryAllocator.Allocate(buffer.Length))
{
- Span innerBuffer = tempBuffer.GetSpan();
+ Span innerBuffer = tempBuffer.Memory.Span;
int count = this.Shape.FindIntersections(start, end, innerBuffer);
for (int i = 0; i < count; i++)
@@ -61,4 +61,4 @@ namespace SixLabors.ImageSharp.Primitives
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp.Drawing/Processing/BrushApplicator.cs b/src/ImageSharp.Drawing/Processing/BrushApplicator.cs
index 7e75d7eff..a9df07ced 100644
--- a/src/ImageSharp.Drawing/Processing/BrushApplicator.cs
+++ b/src/ImageSharp.Drawing/Processing/BrushApplicator.cs
@@ -1,68 +1,85 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Buffers;
-
using SixLabors.ImageSharp.Advanced;
-using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Memory;
namespace SixLabors.ImageSharp.Processing
{
///
- /// primitive that converts a point in to a color for discovering the fill color based on an implementation
+ /// A primitive that converts a point into a color for discovering the fill color based on an implementation.
///
/// The pixel format.
- ///
- public abstract class BrushApplicator : IDisposable // disposable will be required if/when there is an ImageBrush
+ ///
+ public abstract class BrushApplicator : IDisposable
where TPixel : struct, IPixel
{
///
/// Initializes a new instance of the class.
///
+ /// The configuration instance to use when performing operations.
+ /// The graphics options.
/// The target.
- /// The options.
- internal BrushApplicator(ImageFrame target, GraphicsOptions options)
+ internal BrushApplicator(Configuration configuration, GraphicsOptions options, ImageFrame target)
{
+ this.Configuration = configuration;
this.Target = target;
this.Options = options;
this.Blender = PixelOperations.Instance.GetPixelBlender(options);
}
///
- /// Gets the blender
+ /// Gets the configuration instance to use when performing operations.
+ ///
+ protected Configuration Configuration { get; }
+
+ ///
+ /// Gets the pixel blender.
///
internal PixelBlender Blender { get; }
///
- /// Gets the destination
+ /// Gets the target image.
///
protected ImageFrame Target { get; }
///
- /// Gets the blend percentage
+ /// Gets thegraphics options
///
protected GraphicsOptions Options { get; }
///
- /// Gets the color for a single pixel.
+ /// Gets the overlay pixel at the specified position.
///
- /// The x coordinate.
- /// The y coordinate.
- /// The a that should be applied to the pixel.
+ /// The x-coordinate.
+ /// The y-coordinate.
+ /// The at the specified position.
internal abstract TPixel this[int x, int y] { get; }
///
- public abstract void Dispose();
+ public void Dispose()
+ {
+ this.Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Disposes the object and frees resources for the Garbage Collector.
+ ///
+ /// Whether to dispose managed and unmanaged objects.
+ protected virtual void Dispose(bool disposing)
+ {
+ }
///
/// Applies the opacity weighting for each pixel in a scanline to the target based on the pattern contained in the brush.
///
- /// The a collection of opacity values between 0 and 1 to be merged with the brushed color value before being applied to the target.
- /// The x position in the target pixel space that the start of the scanline data corresponds to.
- /// The y position in the target pixel space that whole scanline corresponds to.
+ /// A collection of opacity values between 0 and 1 to be merged with the brushed color value before being applied to the target.
+ /// The x-position in the target pixel space that the start of the scanline data corresponds to.
+ /// The y-position in the target pixel space that whole scanline corresponds to.
/// scanlineBuffer will be > scanlineWidth but provide and offset in case we want to share a larger buffer across runs.
internal virtual void Apply(Span scanline, int x, int y)
{
@@ -71,8 +88,8 @@ namespace SixLabors.ImageSharp.Processing
using (IMemoryOwner amountBuffer = memoryAllocator.Allocate(scanline.Length))
using (IMemoryOwner overlay = memoryAllocator.Allocate(scanline.Length))
{
- Span amountSpan = amountBuffer.GetSpan();
- Span overlaySpan = overlay.GetSpan();
+ Span amountSpan = amountBuffer.Memory.Span;
+ Span overlaySpan = overlay.Memory.Span;
for (int i = 0; i < scanline.Length; i++)
{
@@ -89,7 +106,7 @@ namespace SixLabors.ImageSharp.Processing
}
Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length);
- this.Blender.Blend(this.Target.Configuration, destinationRow, destinationRow, overlaySpan, amountSpan);
+ this.Blender.Blend(this.Configuration, destinationRow, destinationRow, overlaySpan, amountSpan);
}
}
}
diff --git a/src/ImageSharp.Drawing/Processing/EllipticGradientBrush.cs b/src/ImageSharp.Drawing/Processing/EllipticGradientBrush.cs
index 91da332a1..fbab3605d 100644
--- a/src/ImageSharp.Drawing/Processing/EllipticGradientBrush.cs
+++ b/src/ImageSharp.Drawing/Processing/EllipticGradientBrush.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@@ -47,12 +47,14 @@ namespace SixLabors.ImageSharp.Processing
///
public override BrushApplicator CreateApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
ImageFrame source,
- RectangleF region,
- GraphicsOptions options) =>
+ RectangleF region) =>
new RadialGradientBrushApplicator(
- source,
+ configuration,
options,
+ source,
this.center,
this.referenceAxisEnd,
this.axisRatio,
@@ -86,24 +88,26 @@ namespace SixLabors.ImageSharp.Processing
///
/// Initializes a new instance of the class.
///
- /// The target image
- /// The options
- /// Center of the ellipse
+ /// The configuration instance to use when performing operations.
+ /// The graphics options.
+ /// The target image.
+ /// Center of the ellipse.
/// Point on one angular points of the ellipse.
///
/// Ratio of the axis length's. Used to determine the length of the second axis,
/// the first is defined by and .
- /// Definition of colors
+ /// Definition of colors.
/// Defines how the gradient colors are repeated.
public RadialGradientBrushApplicator(
- ImageFrame target,
+ Configuration configuration,
GraphicsOptions options,
+ ImageFrame target,
PointF center,
PointF referenceAxisEnd,
float axisRatio,
ColorStop[] colorStops,
GradientRepetitionMode repetitionMode)
- : base(target, options, colorStops, repetitionMode)
+ : base(configuration, options, target, colorStops, repetitionMode)
{
this.center = center;
this.referenceAxisEnd = referenceAxisEnd;
@@ -122,11 +126,6 @@ namespace SixLabors.ImageSharp.Processing
this.cosRotation = (float)Math.Cos(this.rotation);
}
- ///
- public override void Dispose()
- {
- }
-
///
protected override float PositionOnGradient(float xt, float yt)
{
@@ -139,16 +138,13 @@ namespace SixLabors.ImageSharp.Processing
float xSquared = x * x;
float ySquared = y * y;
- var inBoundaryChecker = (xSquared / this.referenceRadiusSquared)
- + (ySquared / this.secondRadiusSquared);
-
- return inBoundaryChecker;
+ return (xSquared / this.referenceRadiusSquared) + (ySquared / this.secondRadiusSquared);
}
private float AngleBetween(PointF junction, PointF a, PointF b)
{
- var vA = a - junction;
- var vB = b - junction;
+ PointF vA = a - junction;
+ PointF vB = b - junction;
return MathF.Atan2(vB.Y, vB.X) - MathF.Atan2(vA.Y, vA.X);
}
@@ -156,6 +152,7 @@ namespace SixLabors.ImageSharp.Processing
PointF p1,
PointF p2)
{
+ // TODO: Can we not just use Vector2 distance here?
float dX = p1.X - p2.X;
float dXsquared = dX * dX;
@@ -165,4 +162,4 @@ namespace SixLabors.ImageSharp.Processing
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp.Drawing/Processing/Extensions/DrawImageExtensions.cs b/src/ImageSharp.Drawing/Processing/Extensions/DrawImageExtensions.cs
index 981cf1bef..6c7998437 100644
--- a/src/ImageSharp.Drawing/Processing/Extensions/DrawImageExtensions.cs
+++ b/src/ImageSharp.Drawing/Processing/Extensions/DrawImageExtensions.cs
@@ -22,14 +22,17 @@ namespace SixLabors.ImageSharp.Processing
public static IImageProcessingContext DrawImage(
this IImageProcessingContext source,
Image image,
- float opacity) =>
- source.ApplyProcessor(
+ float opacity)
+ {
+ var options = new GraphicsOptions();
+ return source.ApplyProcessor(
new DrawImageProcessor(
- image,
- Point.Empty,
- GraphicsOptions.Default.ColorBlendingMode,
- GraphicsOptions.Default.AlphaCompositionMode,
- opacity));
+ image,
+ Point.Empty,
+ options.ColorBlendingMode,
+ options.AlphaCompositionMode,
+ opacity));
+ }
///
/// Draws the given image together with the current one by blending their pixels.
@@ -49,7 +52,7 @@ namespace SixLabors.ImageSharp.Processing
image,
Point.Empty,
colorBlending,
- GraphicsOptions.Default.AlphaCompositionMode,
+ new GraphicsOptions().AlphaCompositionMode,
opacity));
///
@@ -100,14 +103,17 @@ namespace SixLabors.ImageSharp.Processing
this IImageProcessingContext source,
Image image,
Point location,
- float opacity) =>
- source.ApplyProcessor(
+ float opacity)
+ {
+ var options = new GraphicsOptions();
+ return source.ApplyProcessor(
new DrawImageProcessor(
- image,
- location,
- GraphicsOptions.Default.ColorBlendingMode,
- GraphicsOptions.Default.AlphaCompositionMode,
- opacity));
+ image,
+ location,
+ options.ColorBlendingMode,
+ options.AlphaCompositionMode,
+ opacity));
+ }
///
/// Draws the given image together with the current one by blending their pixels.
@@ -129,7 +135,7 @@ namespace SixLabors.ImageSharp.Processing
image,
location,
colorBlending,
- GraphicsOptions.Default.AlphaCompositionMode,
+ new GraphicsOptions().AlphaCompositionMode,
opacity));
///
@@ -172,4 +178,4 @@ namespace SixLabors.ImageSharp.Processing
options.AlphaCompositionMode,
options.BlendPercentage));
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp.Drawing/Processing/Extensions/DrawPathCollectionExtensions.cs b/src/ImageSharp.Drawing/Processing/Extensions/DrawPathCollectionExtensions.cs
index a68b69a44..90b8c68ac 100644
--- a/src/ImageSharp.Drawing/Processing/Extensions/DrawPathCollectionExtensions.cs
+++ b/src/ImageSharp.Drawing/Processing/Extensions/DrawPathCollectionExtensions.cs
@@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.Processing
/// The .
public static IImageProcessingContext
Draw(this IImageProcessingContext source, IPen pen, IPathCollection paths) =>
- source.Draw(GraphicsOptions.Default, pen, paths);
+ source.Draw(new GraphicsOptions(), pen, paths);
///
/// Draws the outline of the polygon with the provided brush at the provided thickness.
diff --git a/src/ImageSharp.Drawing/Processing/Extensions/DrawPathExtensions.cs b/src/ImageSharp.Drawing/Processing/Extensions/DrawPathExtensions.cs
index dfe30f6a3..822375ca9 100644
--- a/src/ImageSharp.Drawing/Processing/Extensions/DrawPathExtensions.cs
+++ b/src/ImageSharp.Drawing/Processing/Extensions/DrawPathExtensions.cs
@@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Processing
/// The path.
/// The .
public static IImageProcessingContext Draw(this IImageProcessingContext source, IPen pen, IPath path) =>
- source.Draw(GraphicsOptions.Default, pen, path);
+ source.Draw(new GraphicsOptions(), pen, path);
///
/// Draws the outline of the polygon with the provided brush at the provided thickness.
diff --git a/src/ImageSharp.Drawing/Processing/Extensions/DrawPolygonExtensions.cs b/src/ImageSharp.Drawing/Processing/Extensions/DrawPolygonExtensions.cs
index 86d8e9e2e..d51e58645 100644
--- a/src/ImageSharp.Drawing/Processing/Extensions/DrawPolygonExtensions.cs
+++ b/src/ImageSharp.Drawing/Processing/Extensions/DrawPolygonExtensions.cs
@@ -86,7 +86,7 @@ namespace SixLabors.ImageSharp.Processing
this IImageProcessingContext source,
IPen pen,
params PointF[] points) =>
- source.Draw(GraphicsOptions.Default, pen, new Polygon(new LinearLineSegment(points)));
+ source.Draw(new GraphicsOptions(), pen, new Polygon(new LinearLineSegment(points)));
///
/// Draws the provided Points as a closed Linear Polygon with the provided Pen.
diff --git a/src/ImageSharp.Drawing/Processing/Extensions/DrawRectangleExtensions.cs b/src/ImageSharp.Drawing/Processing/Extensions/DrawRectangleExtensions.cs
index da78ab2ec..b3b5dd76a 100644
--- a/src/ImageSharp.Drawing/Processing/Extensions/DrawRectangleExtensions.cs
+++ b/src/ImageSharp.Drawing/Processing/Extensions/DrawRectangleExtensions.cs
@@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Processing
/// The shape.
/// The .
public static IImageProcessingContext Draw(this IImageProcessingContext source, IPen pen, RectangleF shape) =>
- source.Draw(GraphicsOptions.Default, pen, shape);
+ source.Draw(new GraphicsOptions(), pen, shape);
///
/// Draws the outline of the rectangle with the provided brush at the provided thickness.
diff --git a/src/ImageSharp.Drawing/Processing/Extensions/DrawTextExtensions.cs b/src/ImageSharp.Drawing/Processing/Extensions/DrawTextExtensions.cs
index 05cd3a1ae..82dbb8d97 100644
--- a/src/ImageSharp.Drawing/Processing/Extensions/DrawTextExtensions.cs
+++ b/src/ImageSharp.Drawing/Processing/Extensions/DrawTextExtensions.cs
@@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Processing
Font font,
Color color,
PointF location) =>
- source.DrawText(TextGraphicsOptions.Default, text, font, color, location);
+ source.DrawText(new TextGraphicsOptions(), text, font, color, location);
///
/// Draws the text onto the the image filled via the brush.
@@ -69,7 +69,7 @@ namespace SixLabors.ImageSharp.Processing
Font font,
IBrush brush,
PointF location) =>
- source.DrawText(TextGraphicsOptions.Default, text, font, brush, location);
+ source.DrawText(new TextGraphicsOptions(), text, font, brush, location);
///
/// Draws the text onto the the image filled via the brush.
@@ -109,7 +109,7 @@ namespace SixLabors.ImageSharp.Processing
Font font,
IPen pen,
PointF location) =>
- source.DrawText(TextGraphicsOptions.Default, text, font, pen, location);
+ source.DrawText(new TextGraphicsOptions(), text, font, pen, location);
///
/// Draws the text onto the the image outlined via the pen.
@@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.Processing
IBrush brush,
IPen pen,
PointF location) =>
- source.DrawText(TextGraphicsOptions.Default, text, font, brush, pen, location);
+ source.DrawText(new TextGraphicsOptions(), text, font, brush, pen, location);
///
/// Draws the text using the default resolution of 72dpi onto the the image filled via the brush then outlined via the pen.
diff --git a/src/ImageSharp.Drawing/Processing/Extensions/FillPathBuilderExtensions.cs b/src/ImageSharp.Drawing/Processing/Extensions/FillPathBuilderExtensions.cs
index 5de9c6d4e..030fe6ff1 100644
--- a/src/ImageSharp.Drawing/Processing/Extensions/FillPathBuilderExtensions.cs
+++ b/src/ImageSharp.Drawing/Processing/Extensions/FillPathBuilderExtensions.cs
@@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Processing
this IImageProcessingContext source,
IBrush brush,
Action path) =>
- source.Fill(GraphicsOptions.Default, brush, path);
+ source.Fill(new GraphicsOptions(), brush, path);
///
/// Flood fills the image in the shape of the provided polygon with the specified brush.
diff --git a/src/ImageSharp.Drawing/Processing/Extensions/FillPathCollectionExtensions.cs b/src/ImageSharp.Drawing/Processing/Extensions/FillPathCollectionExtensions.cs
index 776e1f7e4..5d8aaf307 100644
--- a/src/ImageSharp.Drawing/Processing/Extensions/FillPathCollectionExtensions.cs
+++ b/src/ImageSharp.Drawing/Processing/Extensions/FillPathCollectionExtensions.cs
@@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Processing
this IImageProcessingContext source,
IBrush brush,
IPathCollection paths) =>
- source.Fill(GraphicsOptions.Default, brush, paths);
+ source.Fill(new GraphicsOptions(), brush, paths);
///
/// Flood fills the image in the shape of the provided polygon with the specified brush.
diff --git a/src/ImageSharp.Drawing/Processing/Extensions/FillPathExtensions.cs b/src/ImageSharp.Drawing/Processing/Extensions/FillPathExtensions.cs
index 718016a9e..4d262aa5f 100644
--- a/src/ImageSharp.Drawing/Processing/Extensions/FillPathExtensions.cs
+++ b/src/ImageSharp.Drawing/Processing/Extensions/FillPathExtensions.cs
@@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Processing
/// The path.
/// The .
public static IImageProcessingContext Fill(this IImageProcessingContext source, IBrush brush, IPath path) =>
- source.Fill(GraphicsOptions.Default, brush, new ShapeRegion(path));
+ source.Fill(new GraphicsOptions(), brush, new ShapeRegion(path));
///
/// Flood fills the image in the shape of the provided polygon with the specified brush..
diff --git a/src/ImageSharp.Drawing/Processing/Extensions/FillRegionExtensions.cs b/src/ImageSharp.Drawing/Processing/Extensions/FillRegionExtensions.cs
index 294e57514..fbb6dbda5 100644
--- a/src/ImageSharp.Drawing/Processing/Extensions/FillRegionExtensions.cs
+++ b/src/ImageSharp.Drawing/Processing/Extensions/FillRegionExtensions.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.Primitives;
@@ -18,7 +18,7 @@ namespace SixLabors.ImageSharp.Processing
/// The details how to fill the region of interest.
/// The .
public static IImageProcessingContext Fill(this IImageProcessingContext source, IBrush brush) =>
- source.Fill(GraphicsOptions.Default, brush);
+ source.Fill(new GraphicsOptions(), brush);
///
/// Flood fills the image with the specified color.
@@ -37,7 +37,7 @@ namespace SixLabors.ImageSharp.Processing
/// The region.
/// The .
public static IImageProcessingContext Fill(this IImageProcessingContext source, IBrush brush, Region region) =>
- source.Fill(GraphicsOptions.Default, brush, region);
+ source.Fill(new GraphicsOptions(), brush, region);
///
/// Flood fills the image with in the region with the specified color.
@@ -77,7 +77,7 @@ namespace SixLabors.ImageSharp.Processing
GraphicsOptions options,
IBrush brush,
Region region) =>
- source.ApplyProcessor(new FillRegionProcessor(brush, region, options));
+ source.ApplyProcessor(new FillRegionProcessor(options, brush, region));
///
/// Flood fills the image with the specified brush.
@@ -90,6 +90,6 @@ namespace SixLabors.ImageSharp.Processing
this IImageProcessingContext source,
GraphicsOptions options,
IBrush brush) =>
- source.ApplyProcessor(new FillProcessor(brush, options));
+ source.ApplyProcessor(new FillProcessor(options, brush));
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp.Drawing/Processing/GradientBrush.cs b/src/ImageSharp.Drawing/Processing/GradientBrush.cs
index 9826748c4..3be56c042 100644
--- a/src/ImageSharp.Drawing/Processing/GradientBrush.cs
+++ b/src/ImageSharp.Drawing/Processing/GradientBrush.cs
@@ -1,11 +1,9 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
-
using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.ImageSharp.PixelFormats.PixelBlenders;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing
@@ -38,9 +36,10 @@ namespace SixLabors.ImageSharp.Processing
///
public abstract BrushApplicator CreateApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
ImageFrame source,
- RectangleF region,
- GraphicsOptions options)
+ RectangleF region)
where TPixel : struct, IPixel;
///
@@ -58,27 +57,24 @@ namespace SixLabors.ImageSharp.Processing
///
/// Initializes a new instance of the class.
///
- /// The target.
- /// The options.
+ /// The configuration instance to use when performing operations.
+ /// The graphics options.
+ /// The target image.
/// An array of color stops sorted by their position.
/// Defines if and how the gradient should be repeated.
protected GradientBrushApplicator(
- ImageFrame target,
+ Configuration configuration,
GraphicsOptions options,
+ ImageFrame target,
ColorStop[] colorStops,
GradientRepetitionMode repetitionMode)
- : base(target, options)
+ : base(configuration, options, target)
{
this.colorStops = colorStops; // TODO: requires colorStops to be sorted by position - should that be checked?
this.repetitionMode = repetitionMode;
}
- ///
- /// Base implementation of the indexer for gradients
- /// (follows the facade pattern, using abstract methods)
- ///
- /// X coordinate of the Pixel.
- /// Y coordinate of the Pixel.
+ ///
internal override TPixel this[int x, int y]
{
get
@@ -92,10 +88,10 @@ namespace SixLabors.ImageSharp.Processing
// onLocalGradient = Math.Min(0, Math.Max(1, onLocalGradient));
break;
case GradientRepetitionMode.Repeat:
- positionOnCompleteGradient = positionOnCompleteGradient % 1;
+ positionOnCompleteGradient %= 1;
break;
case GradientRepetitionMode.Reflect:
- positionOnCompleteGradient = positionOnCompleteGradient % 2;
+ positionOnCompleteGradient %= 2;
if (positionOnCompleteGradient > 1)
{
positionOnCompleteGradient = 2 - positionOnCompleteGradient;
@@ -121,19 +117,8 @@ namespace SixLabors.ImageSharp.Processing
}
else
{
- var fromAsVector = from.Color.ToVector4();
- var toAsVector = to.Color.ToVector4();
float onLocalGradient = (positionOnCompleteGradient - from.Ratio) / (to.Ratio - from.Ratio);
-
- // TODO: this should be changeble for different gradienting functions
- Vector4 result = PorterDuffFunctions.NormalSrcOver(
- fromAsVector,
- toAsVector,
- onLocalGradient);
-
- TPixel resultColor = default;
- resultColor.FromVector4(result);
- return resultColor;
+ return new Color(Vector4.Lerp((Vector4)from.Color, (Vector4)to.Color, onLocalGradient)).ToPixel();
}
}
}
@@ -142,8 +127,8 @@ namespace SixLabors.ImageSharp.Processing
/// calculates the position on the gradient for a given point.
/// This method is abstract as it's content depends on the shape of the gradient.
///
- /// The x coordinate of the point
- /// The y coordinate of the point
+ /// The x-coordinate of the point.
+ /// The y-coordinate of the point.
///
/// The position the given point has on the gradient.
/// The position is not bound to the [0..1] interval.
@@ -176,4 +161,4 @@ namespace SixLabors.ImageSharp.Processing
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp.Drawing/Processing/IBrush.cs b/src/ImageSharp.Drawing/Processing/IBrush.cs
index 0cd2e20fd..f4c7ef7cb 100644
--- a/src/ImageSharp.Drawing/Processing/IBrush.cs
+++ b/src/ImageSharp.Drawing/Processing/IBrush.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
@@ -19,20 +19,22 @@ namespace SixLabors.ImageSharp.Processing
/// Creates the applicator for this brush.
///
/// The pixel type.
+ /// The configuration instance to use when performing operations.
+ /// The graphic options.
/// The source image.
/// The region the brush will be applied to.
- /// The graphic options
///
- /// The brush applicator for this brush
+ /// The for this brush.
///
///
/// The when being applied to things like shapes would usually be the
- /// bounding box of the shape not necessarily the bounds of the whole image
+ /// bounding box of the shape not necessarily the bounds of the whole image.
///
BrushApplicator CreateApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
ImageFrame source,
- RectangleF region,
- GraphicsOptions options)
+ RectangleF region)
where TPixel : struct, IPixel;
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp.Drawing/Processing/ImageBrush.cs b/src/ImageSharp.Drawing/Processing/ImageBrush.cs
index 8485ddfd0..e38614070 100644
--- a/src/ImageSharp.Drawing/Processing/ImageBrush.cs
+++ b/src/ImageSharp.Drawing/Processing/ImageBrush.cs
@@ -1,11 +1,10 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Buffers;
using SixLabors.ImageSharp.Advanced;
-using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives;
@@ -32,19 +31,20 @@ namespace SixLabors.ImageSharp.Processing
///
public BrushApplicator CreateApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
ImageFrame source,
- RectangleF region,
- GraphicsOptions options)
+ RectangleF region)
where TPixel : struct, IPixel
{
if (this.image is Image specificImage)
{
- return new ImageBrushApplicator(source, specificImage, region, options, false);
+ return new ImageBrushApplicator(configuration, options, source, specificImage, region, false);
}
specificImage = this.image.CloneAs();
- return new ImageBrushApplicator(source, specificImage, region, options, true);
+ return new ImageBrushApplicator(configuration, options, source, specificImage, region, true);
}
///
@@ -79,21 +79,25 @@ namespace SixLabors.ImageSharp.Processing
///
private readonly int offsetX;
+ private bool isDisposed;
+
///
/// Initializes a new instance of the class.
///
+ /// The configuration instance to use when performing operations.
+ /// The graphics options.
/// The target image.
/// The image.
/// The region.
- /// The options
/// Whether to dispose the image on disposal of the applicator.
public ImageBrushApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
ImageFrame target,
Image image,
RectangleF region,
- GraphicsOptions options,
bool shouldDisposeImage)
- : base(target, options)
+ : base(configuration, options, target)
{
this.sourceImage = image;
this.sourceFrame = image.Frames.RootFrame;
@@ -104,14 +108,7 @@ namespace SixLabors.ImageSharp.Processing
this.offsetX = (int)MathF.Max(MathF.Floor(region.Left), 0);
}
- ///
- /// Gets the color for a single pixel.
- ///
- /// The x.
- /// The y.
- ///
- /// The color
- ///
+ ///
internal override TPixel this[int x, int y]
{
get
@@ -123,14 +120,21 @@ namespace SixLabors.ImageSharp.Processing
}
///
- public override void Dispose()
+ protected override void Dispose(bool disposing)
{
- if (this.shouldDisposeImage)
+ if (this.isDisposed)
+ {
+ return;
+ }
+
+ if (disposing && this.shouldDisposeImage)
{
this.sourceImage?.Dispose();
- this.sourceImage = null;
- this.sourceFrame = null;
}
+
+ this.sourceImage = null;
+ this.sourceFrame = null;
+ this.isDisposed = true;
}
///
@@ -140,8 +144,8 @@ namespace SixLabors.ImageSharp.Processing
using (IMemoryOwner amountBuffer = this.Target.MemoryAllocator.Allocate(scanline.Length))
using (IMemoryOwner overlay = this.Target.MemoryAllocator.Allocate(scanline.Length))
{
- Span amountSpan = amountBuffer.GetSpan();
- Span overlaySpan = overlay.GetSpan();
+ Span amountSpan = amountBuffer.Memory.Span;
+ Span overlaySpan = overlay.Memory.Span;
int sourceY = (y - this.offsetY) % this.yLength;
int offsetX = x - this.offsetX;
@@ -152,13 +156,12 @@ namespace SixLabors.ImageSharp.Processing
amountSpan[i] = scanline[i] * this.Options.BlendPercentage;
int sourceX = (i + offsetX) % this.xLength;
- TPixel pixel = sourceRow[sourceX];
- overlaySpan[i] = pixel;
+ overlaySpan[i] = sourceRow[sourceX];
}
Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length);
this.Blender.Blend(
- this.sourceFrame.Configuration,
+ this.Configuration,
destinationRow,
destinationRow,
overlaySpan,
@@ -167,4 +170,4 @@ namespace SixLabors.ImageSharp.Processing
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp.Drawing/Processing/LinearGradientBrush.cs b/src/ImageSharp.Drawing/Processing/LinearGradientBrush.cs
index bb99eeb26..044bee72c 100644
--- a/src/ImageSharp.Drawing/Processing/LinearGradientBrush.cs
+++ b/src/ImageSharp.Drawing/Processing/LinearGradientBrush.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@@ -39,16 +39,18 @@ namespace SixLabors.ImageSharp.Processing
///
public override BrushApplicator CreateApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
ImageFrame source,
- RectangleF region,
- GraphicsOptions options) =>
+ RectangleF region) =>
new LinearGradientBrushApplicator(
+ configuration,
+ options,
source,
this.p1,
this.p2,
this.ColorStops,
- this.RepetitionMode,
- options);
+ this.RepetitionMode);
///
/// The linear gradient brush applicator.
@@ -93,20 +95,22 @@ namespace SixLabors.ImageSharp.Processing
///
/// Initializes a new instance of the class.
///
- /// The source
- /// start point of the gradient
- /// end point of the gradient
- /// tuple list of colors and their respective position between 0 and 1 on the line
- /// defines how the gradient colors are repeated.
- /// the graphics options
+ /// The configuration instance to use when performing operations.
+ /// The graphics options.
+ /// The source image.
+ /// The start point of the gradient.
+ /// The end point of the gradient.
+ /// A tuple list of colors and their respective position between 0 and 1 on the line.
+ /// Defines how the gradient colors are repeated.
public LinearGradientBrushApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
ImageFrame source,
PointF start,
PointF end,
ColorStop[] colorStops,
- GradientRepetitionMode repetitionMode,
- GraphicsOptions options)
- : base(source, options, colorStops, repetitionMode)
+ GradientRepetitionMode repetitionMode)
+ : base(configuration, options, source, colorStops, repetitionMode)
{
this.start = start;
this.end = end;
@@ -148,14 +152,9 @@ namespace SixLabors.ImageSharp.Processing
float distance = MathF.Sqrt(MathF.Pow(x4 - this.start.X, 2) + MathF.Pow(y4 - this.start.Y, 2));
// get and return ratio
- float ratio = distance / this.length;
- return ratio;
+ return distance / this.length;
}
}
-
- public override void Dispose()
- {
- }
}
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp.Drawing/Processing/PathGradientBrush.cs b/src/ImageSharp.Drawing/Processing/PathGradientBrush.cs
index 7315dc5a3..9e354120e 100644
--- a/src/ImageSharp.Drawing/Processing/PathGradientBrush.cs
+++ b/src/ImageSharp.Drawing/Processing/PathGradientBrush.cs
@@ -83,12 +83,13 @@ namespace SixLabors.ImageSharp.Processing
///
public BrushApplicator CreateApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
ImageFrame source,
- RectangleF region,
- GraphicsOptions options)
+ RectangleF region)
where TPixel : struct, IPixel
{
- return new PathGradientBrushApplicator(source, this.edges, this.centerColor, options);
+ return new PathGradientBrushApplicator(configuration, options, source, this.edges, this.centerColor);
}
private static Color CalculateCenterColor(Color[] colors)
@@ -105,7 +106,7 @@ namespace SixLabors.ImageSharp.Processing
"One or more color is needed to construct a path gradient brush.");
}
- return new Color(colors.Select(c => c.ToVector4()).Aggregate((p1, p2) => p1 + p2) / colors.Length);
+ return new Color(colors.Select(c => (Vector4)c).Aggregate((p1, p2) => p1 + p2) / colors.Length);
}
private static float DistanceBetween(PointF p1, PointF p2) => ((Vector2)(p2 - p1)).Length();
@@ -141,10 +142,10 @@ namespace SixLabors.ImageSharp.Processing
Vector2[] points = path.LineSegments.SelectMany(s => s.Flatten()).Select(p => (Vector2)p).ToArray();
this.Start = points.First();
- this.StartColor = startColor.ToVector4();
+ this.StartColor = (Vector4)startColor;
this.End = points.Last();
- this.EndColor = endColor.ToVector4();
+ this.EndColor = (Vector4)endColor;
this.length = DistanceBetween(this.End, this.Start);
this.buffer = new PointF[this.path.MaxIntersections];
@@ -199,23 +200,25 @@ namespace SixLabors.ImageSharp.Processing
///
/// Initializes a new instance of the class.
///
+ /// The configuration instance to use when performing operations.
+ /// The graphics options.
/// The source image.
/// Edges of the polygon.
/// Color at the center of the gradient area to which the other colors converge.
- /// The options.
public PathGradientBrushApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
ImageFrame source,
IList edges,
- Color centerColor,
- GraphicsOptions options)
- : base(source, options)
+ Color centerColor)
+ : base(configuration, options, source)
{
this.edges = edges;
PointF[] points = edges.Select(s => s.Start).ToArray();
this.center = points.Aggregate((p1, p2) => p1 + p2) / edges.Count;
- this.centerColor = centerColor.ToVector4();
+ this.centerColor = (Vector4)centerColor;
this.maxDistance = points.Select(p => (Vector2)(p - this.center)).Select(d => d.Length()).Max();
}
@@ -232,7 +235,7 @@ namespace SixLabors.ImageSharp.Processing
return new Color(this.centerColor).ToPixel();
}
- Vector2 direction = Vector2.Normalize(point - this.center);
+ var direction = Vector2.Normalize(point - this.center);
PointF end = point + (PointF)(direction * this.maxDistance);
@@ -250,7 +253,7 @@ namespace SixLabors.ImageSharp.Processing
float length = DistanceBetween(intersection, this.center);
float ratio = length > 0 ? DistanceBetween(intersection, point) / length : 0;
- Vector4 color = Vector4.Lerp(edgeColor, this.centerColor, ratio);
+ var color = Vector4.Lerp(edgeColor, this.centerColor, ratio);
return new Color(color).ToPixel();
}
@@ -277,11 +280,6 @@ namespace SixLabors.ImageSharp.Processing
return closest;
}
-
- ///
- public override void Dispose()
- {
- }
}
}
}
diff --git a/src/ImageSharp.Drawing/Processing/PatternBrush.cs b/src/ImageSharp.Drawing/Processing/PatternBrush.cs
index 1999af8a3..726df5a79 100644
--- a/src/ImageSharp.Drawing/Processing/PatternBrush.cs
+++ b/src/ImageSharp.Drawing/Processing/PatternBrush.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@@ -61,8 +61,8 @@ namespace SixLabors.ImageSharp.Processing
/// The pattern.
internal PatternBrush(Color foreColor, Color backColor, in DenseMatrix pattern)
{
- var foreColorVector = foreColor.ToVector4();
- var backColorVector = backColor.ToVector4();
+ var foreColorVector = (Vector4)foreColor;
+ var backColorVector = (Vector4)backColor;
this.pattern = new DenseMatrix(pattern.Columns, pattern.Rows);
this.patternVector = new DenseMatrix(pattern.Columns, pattern.Rows);
for (int i = 0; i < pattern.Data.Length; i++)
@@ -92,14 +92,16 @@ namespace SixLabors.ImageSharp.Processing
///
public BrushApplicator CreateApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
ImageFrame source,
- RectangleF region,
- GraphicsOptions options)
+ RectangleF region)
where TPixel : struct, IPixel =>
new PatternBrushApplicator(
+ configuration,
+ options,
source,
- this.pattern.ToPixelMatrix(source.Configuration),
- options);
+ this.pattern.ToPixelMatrix(configuration));
///
/// The pattern brush applicator.
@@ -115,41 +117,33 @@ namespace SixLabors.ImageSharp.Processing
///
/// Initializes a new instance of the class.
///
+ /// The configuration instance to use when performing operations.
+ /// The graphics options.
/// The source image.
/// The pattern.
- /// The options
- public PatternBrushApplicator(ImageFrame source, in DenseMatrix pattern, GraphicsOptions options)
- : base(source, options)
+ public PatternBrushApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
+ ImageFrame source,
+ in DenseMatrix pattern)
+ : base(configuration, options, source)
{
this.pattern = pattern;
}
- ///
- /// Gets the color for a single pixel.
- /// #
- /// The x.
- /// The y.
- ///
- /// The Color.
- ///
+ ///
internal override TPixel this[int x, int y]
{
get
{
- x = x % this.pattern.Columns;
- y = y % this.pattern.Rows;
+ x %= this.pattern.Columns;
+ y %= this.pattern.Rows;
// 2d array index at row/column
return this.pattern[y, x];
}
}
- ///
- public override void Dispose()
- {
- // noop
- }
-
///
internal override void Apply(Span scanline, int x, int y)
{
@@ -159,12 +153,12 @@ namespace SixLabors.ImageSharp.Processing
using (IMemoryOwner amountBuffer = memoryAllocator.Allocate(scanline.Length))
using (IMemoryOwner overlay = memoryAllocator.Allocate(scanline.Length))
{
- Span amountSpan = amountBuffer.GetSpan();
- Span overlaySpan = overlay.GetSpan();
+ Span amountSpan = amountBuffer.Memory.Span;
+ Span overlaySpan = overlay.Memory.Span;
for (int i = 0; i < scanline.Length; i++)
{
- amountSpan[i] = (scanline[i] * this.Options.BlendPercentage).Clamp(0, 1);
+ amountSpan[i] = NumberUtils.ClampFloat(scanline[i] * this.Options.BlendPercentage, 0, 1F);
int patternX = (x + i) % this.pattern.Columns;
overlaySpan[i] = this.pattern[patternY, patternX];
@@ -172,7 +166,7 @@ namespace SixLabors.ImageSharp.Processing
Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length);
this.Blender.Blend(
- this.Target.Configuration,
+ this.Configuration,
destinationRow,
destinationRow,
overlaySpan,
@@ -181,4 +175,4 @@ namespace SixLabors.ImageSharp.Processing
}
}
}
-}
\ 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 1d3cf3557..3963f99a5 100644
--- a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor.cs
+++ b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor.cs
@@ -15,9 +15,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
///
/// Initializes a new instance of the class.
///
- /// The brush to use for filling.
/// The defining how to blend the brush pixels over the image pixels.
- public FillProcessor(IBrush brush, GraphicsOptions options)
+ /// The brush to use for filling.
+ public FillProcessor(GraphicsOptions options, IBrush brush)
{
this.Brush = brush;
this.Options = options;
diff --git a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor{TPixel}.cs b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor{TPixel}.cs
index 4e052818d..fc9482618 100644
--- a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor{TPixel}.cs
+++ b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor{TPixel}.cs
@@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
int width = maxX - minX;
- Rectangle workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY);
+ var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY);
IBrush brush = this.definition.Brush;
GraphicsOptions options = this.definition.Options;
@@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
ParallelExecutionSettings parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration)
.MultiplyMinimumPixelsPerTask(4);
- var colorPixel = solidBrush.Color.ToPixel();
+ TPixel colorPixel = solidBrush.Color.ToPixel();
ParallelHelper.IterateRows(
workingRect,
@@ -84,11 +84,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
using (IMemoryOwner amount = source.MemoryAllocator.Allocate(width))
using (BrushApplicator applicator = brush.CreateApplicator(
+ configuration,
+ options,
source,
- sourceRectangle,
- options))
+ sourceRectangle))
{
- amount.GetSpan().Fill(1f);
+ amount.Memory.Span.Fill(1f);
ParallelHelper.IterateRows(
workingRect,
@@ -100,7 +101,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
int offsetY = y - startY;
int offsetX = minX - startX;
- applicator.Apply(amount.GetSpan(), offsetX, offsetY);
+ applicator.Apply(amount.Memory.Span, offsetX, offsetY);
}
});
}
diff --git a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs
index 2318f3168..7d51be1c5 100644
--- a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs
+++ b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs
@@ -16,10 +16,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
///
/// Initializes a new instance of the class.
///
+ /// The graphics options.
/// The details how to fill the region of interest.
/// The region of interest to be filled.
- /// The configuration options.
- public FillRegionProcessor(IBrush brush, Region region, GraphicsOptions options)
+ public FillRegionProcessor(GraphicsOptions options, IBrush brush, Region region)
{
this.Region = region;
this.Brush = brush;
diff --git a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor{TPixel}.cs b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor{TPixel}.cs
index 45d5015ae..4744a4e92 100644
--- a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor{TPixel}.cs
+++ b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor{TPixel}.cs
@@ -71,7 +71,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
}
}
- using (BrushApplicator applicator = brush.CreateApplicator(source, rect, options))
+ using (BrushApplicator applicator = brush.CreateApplicator(configuration, options, source, rect))
{
int scanlineWidth = maxX - minX;
using (IMemoryOwner bBuffer = source.MemoryAllocator.Allocate(maxIntersections))
@@ -81,8 +81,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
float subpixelFraction = 1f / subpixelCount;
float subpixelFractionPoint = subpixelFraction / subpixelCount;
- Span buffer = bBuffer.GetSpan();
- Span scanline = bScanline.GetSpan();
+ Span buffer = bBuffer.Memory.Span;
+ Span scanline = bScanline.Memory.Span;
bool isSolidBrushWithoutBlending = this.IsSolidBrushWithoutBlending(out SolidBrush solidBrush);
TPixel solidBrushColor = isSolidBrushWithoutBlending ? solidBrush.Color.ToPixel() : default;
diff --git a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor{TPixel}.cs b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor{TPixel}.cs
index ea042635d..64d32efb8 100644
--- a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor{TPixel}.cs
+++ b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor{TPixel}.cs
@@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text
VerticalAlignment = this.Options.VerticalAlignment
};
- this.textRenderer = new CachingGlyphRenderer(this.Source.GetMemoryAllocator(), this.Text.Length, this.Pen, this.Brush != null);
+ this.textRenderer = new CachingGlyphRenderer(this.Configuration.MemoryAllocator, this.Text.Length, this.Pen, this.Brush != null);
this.textRenderer.Options = (GraphicsOptions)this.Options;
var renderer = new TextRenderer(this.textRenderer);
renderer.RenderText(this.Text, style);
@@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text
{
if (operations?.Count > 0)
{
- using (BrushApplicator app = brush.CreateApplicator(source, this.SourceRectangle, this.textRenderer.Options))
+ using (BrushApplicator app = brush.CreateApplicator(this.Configuration, this.textRenderer.Options, source, this.SourceRectangle))
{
foreach (DrawingOperation operation in operations)
{
@@ -326,6 +326,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text
{
float subpixelFraction = 1f / subpixelCount;
float subpixelFractionPoint = subpixelFraction / subpixelCount;
+ Span intersectionSpan = rowIntersectionBuffer.Memory.Span;
+ Span buffer = bufferBacking.Memory.Span;
for (int y = 0; y <= size.Height; y++)
{
@@ -337,8 +339,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text
{
var start = new PointF(path.Bounds.Left - 1, subPixel);
var end = new PointF(path.Bounds.Right + 1, subPixel);
- Span intersectionSpan = rowIntersectionBuffer.GetSpan();
- Span buffer = bufferBacking.GetSpan();
int pointsFound = path.FindIntersections(start, end, intersectionSpan);
if (pointsFound == 0)
diff --git a/src/ImageSharp.Drawing/Processing/RadialGradientBrush.cs b/src/ImageSharp.Drawing/Processing/RadialGradientBrush.cs
index f4d2dd81f..2b1b6913f 100644
--- a/src/ImageSharp.Drawing/Processing/RadialGradientBrush.cs
+++ b/src/ImageSharp.Drawing/Processing/RadialGradientBrush.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@@ -9,7 +9,7 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing
{
///
- /// A Circular Gradient Brush, defined by center point and radius.
+ /// A radial gradient brush, defined by center point and radius.
///
public sealed class RadialGradientBrush : GradientBrush
{
@@ -35,12 +35,14 @@ namespace SixLabors.ImageSharp.Processing
///
public override BrushApplicator CreateApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
ImageFrame source,
- RectangleF region,
- GraphicsOptions options) =>
+ RectangleF region) =>
new RadialGradientBrushApplicator(
- source,
+ configuration,
options,
+ source,
this.center,
this.radius,
this.ColorStops,
@@ -57,30 +59,27 @@ namespace SixLabors.ImageSharp.Processing
///
/// Initializes a new instance of the class.
///
- /// The target image
- /// The options.
+ /// The configuration instance to use when performing operations.
+ /// The graphics options.
+ /// The target image.
/// Center point of the gradient.
/// Radius of the gradient.
/// Definition of colors.
/// How the colors are repeated beyond the first gradient.
public RadialGradientBrushApplicator(
- ImageFrame target,
+ Configuration configuration,
GraphicsOptions options,
+ ImageFrame target,
PointF center,
float radius,
ColorStop[] colorStops,
GradientRepetitionMode repetitionMode)
- : base(target, options, colorStops, repetitionMode)
+ : base(configuration, options, target, colorStops, repetitionMode)
{
this.center = center;
this.radius = radius;
}
- ///
- public override void Dispose()
- {
- }
-
///
/// As this is a circular gradient, the position on the gradient is based on
/// the distance of the point to the center.
@@ -90,6 +89,7 @@ namespace SixLabors.ImageSharp.Processing
/// the position on the color gradient.
protected override float PositionOnGradient(float x, float y)
{
+ // TODO: Can this not use Vector2 distance?
float distance = MathF.Sqrt(MathF.Pow(this.center.X - x, 2) + MathF.Pow(this.center.Y - y, 2));
return distance / this.radius;
}
@@ -101,4 +101,4 @@ namespace SixLabors.ImageSharp.Processing
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp.Drawing/Processing/RecolorBrush.cs b/src/ImageSharp.Drawing/Processing/RecolorBrush.cs
index fca95be32..e0e43cf78 100644
--- a/src/ImageSharp.Drawing/Processing/RecolorBrush.cs
+++ b/src/ImageSharp.Drawing/Processing/RecolorBrush.cs
@@ -1,11 +1,10 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Buffers;
using System.Numerics;
using SixLabors.ImageSharp.Advanced;
-using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Memory;
using SixLabors.Primitives;
@@ -38,9 +37,6 @@ namespace SixLabors.ImageSharp.Processing
///
/// Gets the source color.
///
- ///
- /// The color of the source.
- ///
public Color SourceColor { get; }
///
@@ -50,17 +46,19 @@ namespace SixLabors.ImageSharp.Processing
///
public BrushApplicator CreateApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
ImageFrame source,
- RectangleF region,
- GraphicsOptions options)
+ RectangleF region)
where TPixel : struct, IPixel
{
return new RecolorBrushApplicator(
+ configuration,
+ options,
source,
this.SourceColor.ToPixel(),
this.TargetColor.ToPixel(),
- this.Threshold,
- options);
+ this.Threshold);
}
///
@@ -74,11 +72,6 @@ namespace SixLabors.ImageSharp.Processing
///
private readonly Vector4 sourceColor;
- ///
- /// The target color.
- ///
- private readonly Vector4 targetColor;
-
///
/// The threshold.
///
@@ -89,16 +82,22 @@ namespace SixLabors.ImageSharp.Processing
///
/// Initializes a new instance of the class.
///
+ /// The configuration instance to use when performing operations.
+ /// The options
/// The source image.
/// Color of the source.
/// Color of the target.
/// The threshold .
- /// The options
- public RecolorBrushApplicator(ImageFrame source, TPixel sourceColor, TPixel targetColor, float threshold, GraphicsOptions options)
- : base(source, options)
+ public RecolorBrushApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
+ ImageFrame source,
+ TPixel sourceColor,
+ TPixel targetColor,
+ float threshold)
+ : base(configuration, options, source)
{
this.sourceColor = sourceColor.ToVector4();
- this.targetColor = targetColor.ToVector4();
this.targetColorPixel = targetColor;
// Lets hack a min max extremes for a color space by letting the IPackedPixel clamp our values to something in the correct spaces :)
@@ -109,14 +108,7 @@ namespace SixLabors.ImageSharp.Processing
this.threshold = Vector4.DistanceSquared(maxColor.ToVector4(), minColor.ToVector4()) * threshold;
}
- ///
- /// Gets the color for a single pixel.
- ///
- /// The x.
- /// The y.
- ///
- /// The color
- ///
+ ///
internal override TPixel this[int x, int y]
{
get
@@ -138,11 +130,6 @@ namespace SixLabors.ImageSharp.Processing
}
}
- ///
- public override void Dispose()
- {
- }
-
///
internal override void Apply(Span scanline, int x, int y)
{
@@ -151,8 +138,8 @@ namespace SixLabors.ImageSharp.Processing
using (IMemoryOwner amountBuffer = memoryAllocator.Allocate(scanline.Length))
using (IMemoryOwner overlay = memoryAllocator.Allocate(scanline.Length))
{
- Span amountSpan = amountBuffer.GetSpan();
- Span overlaySpan = overlay.GetSpan();
+ Span amountSpan = amountBuffer.Memory.Span;
+ Span overlaySpan = overlay.Memory.Span;
for (int i = 0; i < scanline.Length; i++)
{
@@ -167,7 +154,7 @@ namespace SixLabors.ImageSharp.Processing
Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length);
this.Blender.Blend(
- this.Target.Configuration,
+ this.Configuration,
destinationRow,
destinationRow,
overlaySpan,
@@ -176,4 +163,4 @@ namespace SixLabors.ImageSharp.Processing
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp.Drawing/Processing/SolidBrush.cs b/src/ImageSharp.Drawing/Processing/SolidBrush.cs
index c62566f6b..c297ede21 100644
--- a/src/ImageSharp.Drawing/Processing/SolidBrush.cs
+++ b/src/ImageSharp.Drawing/Processing/SolidBrush.cs
@@ -1,11 +1,10 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Buffers;
using SixLabors.ImageSharp.Advanced;
-using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Memory;
using SixLabors.Primitives;
@@ -17,33 +16,29 @@ namespace SixLabors.ImageSharp.Processing
///
public class SolidBrush : IBrush
{
- ///
- /// The color to paint.
- ///
- private readonly Color color;
-
///
/// Initializes a new instance of the class.
///
/// The color.
public SolidBrush(Color color)
{
- this.color = color;
+ this.Color = color;
}
///
/// Gets the color.
///
- ///
- /// The color.
- ///
- public Color Color => this.color;
+ public Color Color { get; }
///
- public BrushApplicator CreateApplicator(ImageFrame source, RectangleF region, GraphicsOptions options)
+ public BrushApplicator CreateApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
+ ImageFrame source,
+ RectangleF region)
where TPixel : struct, IPixel
{
- return new SolidBrushApplicator(source, this.color.ToPixel(), options);
+ return new SolidBrushApplicator(configuration, options, source, this.Color.ToPixel());
}
///
@@ -52,38 +47,49 @@ namespace SixLabors.ImageSharp.Processing
private class SolidBrushApplicator : BrushApplicator
where TPixel : struct, IPixel
{
+ private bool isDisposed;
+
///
/// Initializes a new instance of the class.
///
+ /// The configuration instance to use when performing operations.
+ /// The graphics options.
/// The source image.
/// The color.
- /// The options
- public SolidBrushApplicator(ImageFrame source, TPixel color, GraphicsOptions options)
- : base(source, options)
+ public SolidBrushApplicator(
+ Configuration configuration,
+ GraphicsOptions options,
+ ImageFrame source,
+ TPixel color)
+ : base(configuration, options, source)
{
this.Colors = source.MemoryAllocator.Allocate(source.Width);
- this.Colors.GetSpan().Fill(color);
+ this.Colors.Memory.Span.Fill(color);
}
///
/// Gets the colors.
///
- protected IMemoryOwner Colors { get; }
+ protected IMemoryOwner Colors { get; private set; }
- ///
- /// Gets the color for a single pixel.
- ///
- /// The x.
- /// The y.
- ///
- /// The color
- ///
- internal override TPixel this[int x, int y] => this.Colors.GetSpan()[x];
+ ///
+ internal override TPixel this[int x, int y] => this.Colors.Memory.Span[x];
///
- public override void Dispose()
+ protected override void Dispose(bool disposing)
{
- this.Colors.Dispose();
+ if (this.isDisposed)
+ {
+ return;
+ }
+
+ if (disposing)
+ {
+ this.Colors.Dispose();
+ }
+
+ this.Colors = null;
+ this.isDisposed = true;
}
///
@@ -102,17 +108,17 @@ namespace SixLabors.ImageSharp.Processing
}
MemoryAllocator memoryAllocator = this.Target.MemoryAllocator;
- Configuration configuration = this.Target.Configuration;
+ Configuration configuration = this.Configuration;
if (this.Options.BlendPercentage == 1f)
{
- this.Blender.Blend(configuration, destinationRow, destinationRow, this.Colors.GetSpan(), scanline);
+ this.Blender.Blend(configuration, destinationRow, destinationRow, this.Colors.Memory.Span, scanline);
}
else
{
using (IMemoryOwner amountBuffer = memoryAllocator.Allocate(scanline.Length))
{
- Span amountSpan = amountBuffer.GetSpan();
+ Span amountSpan = amountBuffer.Memory.Span;
for (int i = 0; i < scanline.Length; i++)
{
@@ -123,11 +129,11 @@ namespace SixLabors.ImageSharp.Processing
configuration,
destinationRow,
destinationRow,
- this.Colors.GetSpan(),
+ this.Colors.Memory.Span,
amountSpan);
}
}
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp.Drawing/Processing/TextGraphicsOptions.cs b/src/ImageSharp.Drawing/Processing/TextGraphicsOptions.cs
index 6c140be72..63730d1bf 100644
--- a/src/ImageSharp.Drawing/Processing/TextGraphicsOptions.cs
+++ b/src/ImageSharp.Drawing/Processing/TextGraphicsOptions.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.Fonts;
@@ -9,120 +9,169 @@ namespace SixLabors.ImageSharp.Processing
///
/// Options for influencing the drawing functions.
///
- public struct TextGraphicsOptions
+ public class TextGraphicsOptions : IDeepCloneable
{
- private const int DefaultTextDpi = 72;
+ private int antialiasSubpixelDepth = 16;
+ private float blendPercentage = 1F;
+ private float tabWidth = 4F;
+ private float dpiX = 72F;
+ private float dpiY = 72F;
///
- /// Represents the default .
+ /// Initializes a new instance of the class.
///
- public static readonly TextGraphicsOptions Default = new TextGraphicsOptions(true);
-
- private float? blendPercentage;
-
- private int? antialiasSubpixelDepth;
-
- private bool? antialias;
-
- private bool? applyKerning;
-
- private float? tabWidth;
-
- private float? dpiX;
-
- private float? dpiY;
-
- private HorizontalAlignment? horizontalAlignment;
-
- private VerticalAlignment? verticalAlignment;
+ public TextGraphicsOptions()
+ {
+ }
- ///
- /// Initializes a new instance of the struct.
- ///
- /// If set to true [enable antialiasing].
- public TextGraphicsOptions(bool enableAntialiasing)
+ private TextGraphicsOptions(TextGraphicsOptions source)
{
- this.applyKerning = true;
- this.tabWidth = 4;
- this.WrapTextWidth = 0;
- this.horizontalAlignment = HorizontalAlignment.Left;
- this.verticalAlignment = VerticalAlignment.Top;
-
- this.antialiasSubpixelDepth = 16;
- this.ColorBlendingMode = PixelColorBlendingMode.Normal;
- this.AlphaCompositionMode = PixelAlphaCompositionMode.SrcOver;
- this.blendPercentage = 1;
- this.antialias = enableAntialiasing;
- this.dpiX = DefaultTextDpi;
- this.dpiY = DefaultTextDpi;
+ this.AlphaCompositionMode = source.AlphaCompositionMode;
+ this.Antialias = source.Antialias;
+ this.AntialiasSubpixelDepth = source.AntialiasSubpixelDepth;
+ this.ApplyKerning = source.ApplyKerning;
+ this.BlendPercentage = source.BlendPercentage;
+ this.ColorBlendingMode = source.ColorBlendingMode;
+ this.DpiX = source.DpiX;
+ this.DpiY = source.DpiY;
+ this.HorizontalAlignment = source.HorizontalAlignment;
+ this.TabWidth = source.TabWidth;
+ this.WrapTextWidth = source.WrapTextWidth;
+ this.VerticalAlignment = source.VerticalAlignment;
}
///
/// Gets or sets a value indicating whether antialiasing should be applied.
+ /// Defaults to true.
///
- public bool Antialias { get => this.antialias ?? true; set => this.antialias = value; }
+ public bool Antialias { get; set; } = true;
///
/// Gets or sets a value indicating the number of subpixels to use while rendering with antialiasing enabled.
///
- public int AntialiasSubpixelDepth { get => this.antialiasSubpixelDepth ?? 16; set => this.antialiasSubpixelDepth = value; }
+ public int AntialiasSubpixelDepth
+ {
+ get
+ {
+ return this.antialiasSubpixelDepth;
+ }
+
+ set
+ {
+ Guard.MustBeGreaterThanOrEqualTo(value, 0, nameof(this.AntialiasSubpixelDepth));
+ this.antialiasSubpixelDepth = value;
+ }
+ }
///
- /// Gets or sets a value indicating the blending percentage to apply to the drawing operation
+ /// Gets or sets a value indicating the blending percentage to apply to the drawing operation.
///
- public float BlendPercentage { get => (this.blendPercentage ?? 1).Clamp(0, 1); set => this.blendPercentage = value; }
+ public float BlendPercentage
+ {
+ get
+ {
+ return this.blendPercentage;
+ }
- // In the future we could expose a PixelBlender directly on here
- // or some forms of PixelBlender factory for each pixel type. Will need
- // some API thought post V1.
+ set
+ {
+ Guard.MustBeBetweenOrEqualTo(value, 0, 1F, nameof(this.BlendPercentage));
+ this.blendPercentage = value;
+ }
+ }
///
- /// Gets or sets a value indicating the color blending percentage to apply to the drawing operation
+ /// Gets or sets a value indicating the color blending percentage to apply to the drawing operation.
+ /// Defaults to .
///
- public PixelColorBlendingMode ColorBlendingMode { get; set; }
+ public PixelColorBlendingMode ColorBlendingMode { get; set; } = PixelColorBlendingMode.Normal;
///
/// Gets or sets a value indicating the color blending percentage to apply to the drawing operation
+ /// Defaults to .
///
- public PixelAlphaCompositionMode AlphaCompositionMode { get; set; }
+ public PixelAlphaCompositionMode AlphaCompositionMode { get; set; } = PixelAlphaCompositionMode.SrcOver;
///
/// Gets or sets a value indicating whether the text should be drawing with kerning enabled.
+ /// Defaults to true;
///
- public bool ApplyKerning { get => this.applyKerning ?? true; set => this.applyKerning = value; }
+ public bool ApplyKerning { get; set; } = true;
///
/// Gets or sets a value indicating the number of space widths a tab should lock to.
+ /// Defaults to 4.
///
- public float TabWidth { get => this.tabWidth ?? 4; set => this.tabWidth = value; }
+ public float TabWidth
+ {
+ get
+ {
+ return this.tabWidth;
+ }
+
+ set
+ {
+ Guard.MustBeGreaterThanOrEqualTo(value, 0, nameof(this.TabWidth));
+ this.tabWidth = value;
+ }
+ }
///
- /// Gets or sets a value indicating if greater than zero determine the width at which text should wrap.
+ /// Gets or sets a value, if greater than 0, indicating the width at which text should wrap.
+ /// Defaults to 0.
///
public float WrapTextWidth { get; set; }
///
- /// Gets or sets a value indicating the DPI to render text along the X axis.
+ /// Gets or sets a value indicating the DPI (Dots Per Inch) to render text along the X axis.
+ /// Defaults to 72.
///
- public float DpiX { get => this.dpiX ?? DefaultTextDpi; set => this.dpiX = value; }
+ public float DpiX
+ {
+ get
+ {
+ return this.dpiX;
+ }
+
+ set
+ {
+ Guard.MustBeGreaterThanOrEqualTo(value, 0, nameof(this.DpiX));
+ this.dpiX = value;
+ }
+ }
///
- /// Gets or sets a value indicating the DPI to render text along the Y axis.
+ /// Gets or sets a value indicating the DPI (Dots Per Inch) to render text along the Y axis.
+ /// Defaults to 72.
///
- public float DpiY { get => this.dpiY ?? DefaultTextDpi; set => this.dpiY = value; }
+ public float DpiY
+ {
+ get
+ {
+ return this.dpiY;
+ }
+
+ set
+ {
+ Guard.MustBeGreaterThanOrEqualTo(value, 0, nameof(this.DpiY));
+ this.dpiY = value;
+ }
+ }
///
/// Gets or sets a value indicating how to align the text relative to the rendering space.
/// If is greater than zero it will align relative to the space
/// defined by the location and width, if equals zero, and thus
/// wrapping disabled, then the alignment is relative to the drawing location.
+ /// Defaults to .
///
- public HorizontalAlignment HorizontalAlignment { get => this.horizontalAlignment ?? HorizontalAlignment.Left; set => this.horizontalAlignment = value; }
+ public HorizontalAlignment HorizontalAlignment { get; set; } = HorizontalAlignment.Left;
///
/// Gets or sets a value indicating how to align the text relative to the rendering space.
+ /// Defaults to .
///
- public VerticalAlignment VerticalAlignment { get => this.verticalAlignment ?? VerticalAlignment.Top; set => this.verticalAlignment = value; }
+ public VerticalAlignment VerticalAlignment { get; set; } = VerticalAlignment.Top;
///
/// Performs an implicit conversion from to .
@@ -133,8 +182,9 @@ namespace SixLabors.ImageSharp.Processing
///
public static implicit operator TextGraphicsOptions(GraphicsOptions options)
{
- return new TextGraphicsOptions(options.Antialias)
+ return new TextGraphicsOptions()
{
+ Antialias = options.Antialias,
AntialiasSubpixelDepth = options.AntialiasSubpixelDepth,
blendPercentage = options.BlendPercentage,
ColorBlendingMode = options.ColorBlendingMode,
@@ -151,13 +201,17 @@ namespace SixLabors.ImageSharp.Processing
///
public static explicit operator GraphicsOptions(TextGraphicsOptions options)
{
- return new GraphicsOptions(options.Antialias)
+ return new GraphicsOptions()
{
+ Antialias = options.Antialias,
AntialiasSubpixelDepth = options.AntialiasSubpixelDepth,
ColorBlendingMode = options.ColorBlendingMode,
AlphaCompositionMode = options.AlphaCompositionMode,
BlendPercentage = options.BlendPercentage
};
}
+
+ ///
+ public TextGraphicsOptions DeepClone() => new TextGraphicsOptions(this);
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp.Drawing/Utils/NumberUtils.cs b/src/ImageSharp.Drawing/Utils/NumberUtils.cs
new file mode 100644
index 000000000..d034c5d7e
--- /dev/null
+++ b/src/ImageSharp.Drawing/Utils/NumberUtils.cs
@@ -0,0 +1,29 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System.Runtime.CompilerServices;
+
+namespace SixLabors.ImageSharp
+{
+ ///
+ /// Utility methods for numeric primitives.
+ ///
+ internal static class NumberUtils
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float ClampFloat(float value, float min, float max)
+ {
+ if (value >= max)
+ {
+ return max;
+ }
+
+ if (value <= min)
+ {
+ return min;
+ }
+
+ return value;
+ }
+ }
+}
diff --git a/src/ImageSharp.Drawing/Utils/QuickSort.cs b/src/ImageSharp.Drawing/Utils/QuickSort.cs
index ca1da5505..14e3146a0 100644
--- a/src/ImageSharp.Drawing/Utils/QuickSort.cs
+++ b/src/ImageSharp.Drawing/Utils/QuickSort.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
diff --git a/src/ImageSharp/Color/Color.cs b/src/ImageSharp/Color/Color.cs
index 76f399517..5fad7a8e3 100644
--- a/src/ImageSharp/Color/Color.cs
+++ b/src/ImageSharp/Color/Color.cs
@@ -133,8 +133,7 @@ namespace SixLabors.ImageSharp
public override string ToString() => this.ToHex();
///
- /// Converts the color instance to an
- /// implementation defined by .
+ /// Converts the color instance to a specified type.
///
/// The pixel type to convert to.
/// The pixel value.
@@ -147,6 +146,24 @@ namespace SixLabors.ImageSharp
return pixel;
}
+ ///
+ /// Bulk converts a span of to a span of a specified type.
+ ///
+ /// The pixel type to convert to.
+ /// The configuration.
+ /// The source color span.
+ /// The destination pixel span.
+ [MethodImpl(InliningOptions.ShortMethod)]
+ public static void ToPixel(
+ Configuration configuration,
+ ReadOnlySpan source,
+ Span destination)
+ where TPixel : struct, IPixel
+ {
+ ReadOnlySpan rgba64Span = MemoryMarshal.Cast(source);
+ PixelOperations.Instance.FromRgba64(configuration, rgba64Span, destination);
+ }
+
///
[MethodImpl(InliningOptions.ShortMethod)]
public bool Equals(Color other)
@@ -166,19 +183,5 @@ namespace SixLabors.ImageSharp
{
return this.data.PackedValue.GetHashCode();
}
-
- ///
- /// Bulk convert a span of to a span of a specified pixel type.
- ///
- [MethodImpl(InliningOptions.ShortMethod)]
- internal static void ToPixel(
- Configuration configuration,
- ReadOnlySpan source,
- Span destination)
- where TPixel : struct, IPixel
- {
- ReadOnlySpan rgba64Span = MemoryMarshal.Cast(source);
- PixelOperations.Instance.FromRgba64(configuration, rgba64Span, destination);
- }
}
}
diff --git a/src/ImageSharp/GraphicsOptions.cs b/src/ImageSharp/GraphicsOptions.cs
index 214b10810..47b930e65 100644
--- a/src/ImageSharp/GraphicsOptions.cs
+++ b/src/ImageSharp/GraphicsOptions.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
@@ -8,170 +8,82 @@ namespace SixLabors.ImageSharp
///
/// Options for influencing the drawing functions.
///
- public struct GraphicsOptions
+ public class GraphicsOptions : IDeepCloneable
{
- ///
- /// Represents the default .
- ///
- public static readonly GraphicsOptions Default = new GraphicsOptions(true);
-
- private float? blendPercentage;
-
- private int? antialiasSubpixelDepth;
-
- private bool? antialias;
-
- private PixelColorBlendingMode colorBlendingMode;
-
- private PixelAlphaCompositionMode alphaCompositionMode;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// If set to true [enable antialiasing].
- public GraphicsOptions(bool enableAntialiasing)
- {
- this.colorBlendingMode = PixelColorBlendingMode.Normal;
- this.alphaCompositionMode = PixelAlphaCompositionMode.SrcOver;
- this.blendPercentage = 1;
- this.antialiasSubpixelDepth = 16;
- this.antialias = enableAntialiasing;
- }
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// If set to true [enable antialiasing].
- /// blending percentage to apply to the drawing operation
- public GraphicsOptions(bool enableAntialiasing, float opacity)
- {
- Guard.MustBeBetweenOrEqualTo(opacity, 0, 1, nameof(opacity));
-
- this.colorBlendingMode = PixelColorBlendingMode.Normal;
- this.alphaCompositionMode = PixelAlphaCompositionMode.SrcOver;
- this.blendPercentage = opacity;
- this.antialiasSubpixelDepth = 16;
- this.antialias = enableAntialiasing;
- }
+ private int antialiasSubpixelDepth = 16;
+ private float blendPercentage = 1F;
///
- /// Initializes a new instance of the struct.
+ /// Initializes a new instance of the class.
///
- /// If set to true [enable antialiasing].
- /// blending percentage to apply to the drawing operation
- /// color blending mode to apply to the drawing operation
- public GraphicsOptions(bool enableAntialiasing, PixelColorBlendingMode blending, float opacity)
+ public GraphicsOptions()
{
- Guard.MustBeBetweenOrEqualTo(opacity, 0, 1, nameof(opacity));
-
- this.colorBlendingMode = blending;
- this.alphaCompositionMode = PixelAlphaCompositionMode.SrcOver;
- this.blendPercentage = opacity;
- this.antialiasSubpixelDepth = 16;
- this.antialias = enableAntialiasing;
}
- ///
- /// Initializes a new instance of the struct.
- ///
- /// If set to true [enable antialiasing].
- /// blending percentage to apply to the drawing operation
- /// color blending mode to apply to the drawing operation
- /// alpha composition mode to apply to the drawing operation
- public GraphicsOptions(bool enableAntialiasing, PixelColorBlendingMode blending, PixelAlphaCompositionMode composition, float opacity)
+ private GraphicsOptions(GraphicsOptions source)
{
- Guard.MustBeBetweenOrEqualTo(opacity, 0, 1, nameof(opacity));
-
- this.colorBlendingMode = blending;
- this.alphaCompositionMode = composition;
- this.blendPercentage = opacity;
- this.antialiasSubpixelDepth = 16;
- this.antialias = enableAntialiasing;
+ this.AlphaCompositionMode = source.AlphaCompositionMode;
+ this.Antialias = source.Antialias;
+ this.AntialiasSubpixelDepth = source.AntialiasSubpixelDepth;
+ this.BlendPercentage = source.BlendPercentage;
+ this.ColorBlendingMode = source.ColorBlendingMode;
}
///
/// Gets or sets a value indicating whether antialiasing should be applied.
+ /// Defaults to true.
///
- public bool Antialias
- {
- get => this.antialias ?? true;
- set => this.antialias = value;
- }
+ public bool Antialias { get; set; } = true;
///
/// Gets or sets a value indicating the number of subpixels to use while rendering with antialiasing enabled.
+ /// Defaults to 16.
///
public int AntialiasSubpixelDepth
{
- get => this.antialiasSubpixelDepth ?? 16;
- set => this.antialiasSubpixelDepth = value;
+ get
+ {
+ return this.antialiasSubpixelDepth;
+ }
+
+ set
+ {
+ Guard.MustBeGreaterThanOrEqualTo(value, 0, nameof(this.AntialiasSubpixelDepth));
+ this.antialiasSubpixelDepth = value;
+ }
}
///
- /// Gets or sets a value indicating the blending percentage to apply to the drawing operation
+ /// Gets or sets a value between indicating the blending percentage to apply to the drawing operation.
+ /// Range 0..1; Defaults to 1.
///
public float BlendPercentage
{
- get => (this.blendPercentage ?? 1).Clamp(0, 1);
- set => this.blendPercentage = value;
- }
+ get
+ {
+ return this.blendPercentage;
+ }
- // In the future we could expose a PixelBlender directly on here
- // or some forms of PixelBlender factory for each pixel type. Will need
- // some API thought post V1.
+ set
+ {
+ Guard.MustBeBetweenOrEqualTo(value, 0, 1F, nameof(this.BlendPercentage));
+ this.blendPercentage = value;
+ }
+ }
///
- /// Gets or sets a value indicating the color blending mode to apply to the drawing operation
+ /// Gets or sets a value indicating the color blending mode to apply to the drawing operation.
+ /// Defaults to .
///
- public PixelColorBlendingMode ColorBlendingMode
- {
- get => this.colorBlendingMode;
- set => this.colorBlendingMode = value;
- }
+ public PixelColorBlendingMode ColorBlendingMode { get; set; } = PixelColorBlendingMode.Normal;
///
/// Gets or sets a value indicating the alpha composition mode to apply to the drawing operation
+ /// Defaults to .
///
- public PixelAlphaCompositionMode AlphaCompositionMode
- {
- get => this.alphaCompositionMode;
- set => this.alphaCompositionMode = value;
- }
+ public PixelAlphaCompositionMode AlphaCompositionMode { get; set; } = PixelAlphaCompositionMode.SrcOver;
- ///
- /// Evaluates if a given SOURCE color can completely replace a BACKDROP color given the current blending and composition settings.
- ///
- /// the color
- /// true if the color can be considered opaque
- ///
- /// Blending and composition is an expensive operation, in some cases, like
- /// filling with a solid color, the blending can be avoided by a plain color replacement.
- /// This method can be useful for such processors to select the fast path.
- ///
- internal bool IsOpaqueColorWithoutBlending(Color color)
- {
- if (this.ColorBlendingMode != PixelColorBlendingMode.Normal)
- {
- return false;
- }
-
- if (this.AlphaCompositionMode != PixelAlphaCompositionMode.SrcOver &&
- this.AlphaCompositionMode != PixelAlphaCompositionMode.Src)
- {
- return false;
- }
-
- if (this.BlendPercentage != 1f)
- {
- return false;
- }
-
- if (color.ToVector4().W != 1f)
- {
- return false;
- }
-
- return true;
- }
+ ///
+ public GraphicsOptions DeepClone() => new GraphicsOptions(this);
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp/Memory/MemoryAllocatorExtensions.cs b/src/ImageSharp/Memory/MemoryAllocatorExtensions.cs
index b596351b5..a3fa0e1ff 100644
--- a/src/ImageSharp/Memory/MemoryAllocatorExtensions.cs
+++ b/src/ImageSharp/Memory/MemoryAllocatorExtensions.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Buffers;
@@ -11,8 +11,18 @@ namespace SixLabors.ImageSharp.Memory
///
/// Extension methods for .
///
- internal static class MemoryAllocatorExtensions
+ public static class MemoryAllocatorExtensions
{
+ ///
+ /// Allocates a buffer of value type objects interpreted as a 2D region
+ /// of x elements.
+ ///
+ /// The type of buffer items to allocate.
+ /// The memory allocator.
+ /// The buffer width.
+ /// The buffer heght.
+ /// The allocation options.
+ /// The .
public static Buffer2D Allocate2D(
this MemoryAllocator memoryAllocator,
int width,
@@ -26,6 +36,15 @@ namespace SixLabors.ImageSharp.Memory
return new Buffer2D(memorySource, width, height);
}
+ ///
+ /// Allocates a buffer of value type objects interpreted as a 2D region
+ /// of width x height elements.
+ ///
+ /// The type of buffer items to allocate.
+ /// The memory allocator.
+ /// The buffer size.
+ /// The allocation options.
+ /// The .
public static Buffer2D Allocate2D(
this MemoryAllocator memoryAllocator,
Size size,
@@ -41,7 +60,7 @@ namespace SixLabors.ImageSharp.Memory
/// The pixel size in bytes, eg. 3 for RGB
/// The padding
/// A
- public static IManagedByteBuffer AllocatePaddedPixelRowBuffer(
+ internal static IManagedByteBuffer AllocatePaddedPixelRowBuffer(
this MemoryAllocator memoryAllocator,
int width,
int pixelSizeInBytes,
@@ -51,4 +70,4 @@ namespace SixLabors.ImageSharp.Memory
return memoryAllocator.AllocateManagedByteBuffer(length);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp/Primitives/DenseMatrix{T}.cs b/src/ImageSharp/Primitives/DenseMatrix{T}.cs
index 170292e29..cc5e4a90a 100644
--- a/src/ImageSharp/Primitives/DenseMatrix{T}.cs
+++ b/src/ImageSharp/Primitives/DenseMatrix{T}.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@@ -98,9 +98,9 @@ namespace SixLabors.ImageSharp.Primitives
}
///
- /// Gets a Span wrapping the Data.
+ /// Gets a span wrapping the .
///
- internal Span Span => new Span(this.Data);
+ public Span Span => new Span(this.Data);
///
/// Gets or sets the item at the specified position.
@@ -222,4 +222,4 @@ namespace SixLabors.ImageSharp.Primitives
///
public override int GetHashCode() => this.Data.GetHashCode();
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp/Processing/Extensions/BackgroundColorExtensions.cs b/src/ImageSharp/Processing/Extensions/BackgroundColorExtensions.cs
index dd1cc1ed2..4241721f4 100644
--- a/src/ImageSharp/Processing/Extensions/BackgroundColorExtensions.cs
+++ b/src/ImageSharp/Processing/Extensions/BackgroundColorExtensions.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.Processing.Processors.Overlays;
@@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Processing
/// The color to set as the background.
/// The to allow chaining of operations.
public static IImageProcessingContext BackgroundColor(this IImageProcessingContext source, Color color) =>
- BackgroundColor(source, GraphicsOptions.Default, color);
+ BackgroundColor(source, new GraphicsOptions(), color);
///
/// Replaces the background color of image with the given one.
@@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Processing
this IImageProcessingContext source,
Color color,
Rectangle rectangle) =>
- BackgroundColor(source, GraphicsOptions.Default, color, rectangle);
+ BackgroundColor(source, new GraphicsOptions(), color, rectangle);
///
/// Replaces the background color of image with the given one.
@@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Processing
this IImageProcessingContext source,
GraphicsOptions options,
Color color) =>
- source.ApplyProcessor(new BackgroundColorProcessor(color, options));
+ source.ApplyProcessor(new BackgroundColorProcessor(options, color));
///
/// Replaces the background color of image with the given one.
@@ -64,6 +64,6 @@ namespace SixLabors.ImageSharp.Processing
GraphicsOptions options,
Color color,
Rectangle rectangle) =>
- source.ApplyProcessor(new BackgroundColorProcessor(color, options), rectangle);
+ source.ApplyProcessor(new BackgroundColorProcessor(options, color), rectangle);
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp/Processing/Extensions/GlowExtensions.cs b/src/ImageSharp/Processing/Extensions/GlowExtensions.cs
index 39734882b..48ecb5108 100644
--- a/src/ImageSharp/Processing/Extensions/GlowExtensions.cs
+++ b/src/ImageSharp/Processing/Extensions/GlowExtensions.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.Primitives;
@@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Processing
/// The image this method extends.
/// The to allow chaining of operations.
public static IImageProcessingContext Glow(this IImageProcessingContext source) =>
- Glow(source, GraphicsOptions.Default);
+ Glow(source, new GraphicsOptions());
///
/// Applies a radial glow effect to an image.
@@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Processing
/// The to allow chaining of operations.
public static IImageProcessingContext Glow(this IImageProcessingContext source, Color color)
{
- return Glow(source, GraphicsOptions.Default, color);
+ return Glow(source, new GraphicsOptions(), color);
}
///
@@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Processing
/// The the radius.
/// The to allow chaining of operations.
public static IImageProcessingContext Glow(this IImageProcessingContext source, float radius) =>
- Glow(source, GraphicsOptions.Default, radius);
+ Glow(source, new GraphicsOptions(), radius);
///
/// Applies a radial glow effect to an image.
@@ -50,7 +50,7 @@ namespace SixLabors.ImageSharp.Processing
///
/// The to allow chaining of operations.
public static IImageProcessingContext Glow(this IImageProcessingContext source, Rectangle rectangle) =>
- source.Glow(GraphicsOptions.Default, rectangle);
+ source.Glow(new GraphicsOptions(), rectangle);
///
/// Applies a radial glow effect to an image.
@@ -67,7 +67,7 @@ namespace SixLabors.ImageSharp.Processing
Color color,
float radius,
Rectangle rectangle) =>
- source.Glow(GraphicsOptions.Default, color, ValueSize.Absolute(radius), rectangle);
+ source.Glow(new GraphicsOptions(), color, ValueSize.Absolute(radius), rectangle);
///
/// Applies a radial glow effect to an image.
@@ -155,7 +155,7 @@ namespace SixLabors.ImageSharp.Processing
Color color,
ValueSize radius,
Rectangle rectangle) =>
- source.ApplyProcessor(new GlowProcessor(color, radius, options), rectangle);
+ source.ApplyProcessor(new GlowProcessor(options, color, radius), rectangle);
///
/// Applies a radial glow effect to an image.
@@ -170,6 +170,6 @@ namespace SixLabors.ImageSharp.Processing
GraphicsOptions options,
Color color,
ValueSize radius) =>
- source.ApplyProcessor(new GlowProcessor(color, radius, options));
+ source.ApplyProcessor(new GlowProcessor(options, color, radius));
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp/Processing/Extensions/VignetteExtensions.cs b/src/ImageSharp/Processing/Extensions/VignetteExtensions.cs
index 74a59d3e1..a1f3a6e8a 100644
--- a/src/ImageSharp/Processing/Extensions/VignetteExtensions.cs
+++ b/src/ImageSharp/Processing/Extensions/VignetteExtensions.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.Primitives;
@@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Processing
/// The image this method extends.
/// The to allow chaining of operations.
public static IImageProcessingContext Vignette(this IImageProcessingContext source) =>
- Vignette(source, GraphicsOptions.Default);
+ Vignette(source, new GraphicsOptions());
///
/// Applies a radial vignette effect to an image.
@@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Processing
/// The color to set as the vignette.
/// The to allow chaining of operations.
public static IImageProcessingContext Vignette(this IImageProcessingContext source, Color color) =>
- Vignette(source, GraphicsOptions.Default, color);
+ Vignette(source, new GraphicsOptions(), color);
///
/// Applies a radial vignette effect to an image.
@@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.Processing
this IImageProcessingContext source,
float radiusX,
float radiusY) =>
- Vignette(source, GraphicsOptions.Default, radiusX, radiusY);
+ Vignette(source, new GraphicsOptions(), radiusX, radiusY);
///
/// Applies a radial vignette effect to an image.
@@ -52,7 +52,7 @@ namespace SixLabors.ImageSharp.Processing
///
/// The to allow chaining of operations.
public static IImageProcessingContext Vignette(this IImageProcessingContext source, Rectangle rectangle) =>
- Vignette(source, GraphicsOptions.Default, rectangle);
+ Vignette(source, new GraphicsOptions(), rectangle);
///
/// Applies a radial vignette effect to an image.
@@ -71,7 +71,7 @@ namespace SixLabors.ImageSharp.Processing
float radiusX,
float radiusY,
Rectangle rectangle) =>
- source.Vignette(GraphicsOptions.Default, color, radiusX, radiusY, rectangle);
+ source.Vignette(new GraphicsOptions(), color, radiusX, radiusY, rectangle);
///
/// Applies a radial vignette effect to an image.
@@ -166,7 +166,7 @@ namespace SixLabors.ImageSharp.Processing
ValueSize radiusX,
ValueSize radiusY,
Rectangle rectangle) =>
- source.ApplyProcessor(new VignetteProcessor(color, radiusX, radiusY, options), rectangle);
+ source.ApplyProcessor(new VignetteProcessor(options, color, radiusX, radiusY), rectangle);
private static IImageProcessingContext VignetteInternal(
this IImageProcessingContext source,
@@ -174,6 +174,6 @@ namespace SixLabors.ImageSharp.Processing
Color color,
ValueSize radiusX,
ValueSize radiusY) =>
- source.ApplyProcessor(new VignetteProcessor(color, radiusX, radiusY, options));
+ source.ApplyProcessor(new VignetteProcessor(options, color, radiusX, radiusY));
}
-}
\ No newline at end of file
+}
diff --git a/src/ImageSharp/Processing/Processors/Overlays/BackgroundColorProcessor.cs b/src/ImageSharp/Processing/Processors/Overlays/BackgroundColorProcessor.cs
index 4b4c53727..e78f7e5e7 100644
--- a/src/ImageSharp/Processing/Processors/Overlays/BackgroundColorProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Overlays/BackgroundColorProcessor.cs
@@ -14,9 +14,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
///
/// Initializes a new instance of the class.
///
- /// The to set the background color to.
/// The options defining blending algorithm and amount.
- public BackgroundColorProcessor(Color color, GraphicsOptions options)
+ /// The to set the background color to.
+ public BackgroundColorProcessor(GraphicsOptions options, Color color)
{
this.Color = color;
this.GraphicsOptions = options;
diff --git a/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs b/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs
index 0958e3aa9..4b9a23eff 100644
--- a/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs
@@ -24,10 +24,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
///
/// Initializes a new instance of the class.
///
- /// The color or the glow.
/// The options effecting blending and composition.
- public GlowProcessor(Color color, GraphicsOptions options)
- : this(color, 0, options)
+ /// The color or the glow.
+ public GlowProcessor(GraphicsOptions options, Color color)
+ : this(options, color, 0)
{
}
@@ -37,17 +37,17 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
/// The color or the glow.
/// The radius of the glow.
internal GlowProcessor(Color color, ValueSize radius)
- : this(color, radius, GraphicsOptions.Default)
+ : this(new GraphicsOptions(), color, radius)
{
}
///
/// Initializes a new instance of the class.
///
+ /// The options effecting blending and composition.
/// The color or the glow.
/// The radius of the glow.
- /// The options effecting blending and composition.
- internal GlowProcessor(Color color, ValueSize radius, GraphicsOptions options)
+ internal GlowProcessor(GraphicsOptions options, Color color, ValueSize radius)
{
this.GlowColor = color;
this.Radius = radius;
@@ -67,7 +67,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
///
/// Gets the the radius.
///
- internal ValueSize Radius { get; }
+ internal ValueSize Radius { get; }
///
public IImageProcessor CreatePixelSpecificProcessor(Image source, Rectangle sourceRectangle)
diff --git a/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs b/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs
index 2365318f3..3cf48e5a4 100644
--- a/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs
@@ -17,16 +17,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
///
/// The color of the vignette.
public VignetteProcessor(Color color)
- : this(color, GraphicsOptions.Default)
+ : this(new GraphicsOptions(), color)
{
}
///
/// Initializes a new instance of the class.
///
- /// The color of the vignette.
/// The options effecting blending and composition.
- public VignetteProcessor(Color color, GraphicsOptions options)
+ /// The color of the vignette.
+ public VignetteProcessor(GraphicsOptions options, Color color)
{
this.VignetteColor = color;
this.GraphicsOptions = options;
@@ -35,11 +35,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
///
/// Initializes a new instance of the class.
///
+ /// The options effecting blending and composition.
/// The color of the vignette.
/// The x-radius.
/// The y-radius.
- /// The options effecting blending and composition.
- internal VignetteProcessor(Color color, ValueSize radiusX, ValueSize radiusY, GraphicsOptions options)
+ internal VignetteProcessor(GraphicsOptions options, Color color, ValueSize radiusX, ValueSize radiusY)
{
this.VignetteColor = color;
this.RadiusX = radiusX;
diff --git a/tests/ImageSharp.Benchmarks/Drawing/DrawText.cs b/tests/ImageSharp.Benchmarks/Drawing/DrawText.cs
index 0982db334..c19961390 100644
--- a/tests/ImageSharp.Benchmarks/Drawing/DrawText.cs
+++ b/tests/ImageSharp.Benchmarks/Drawing/DrawText.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Drawing;
@@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp.Benchmarks
graphics.SmoothingMode = SmoothingMode.AntiAlias;
using (var font = new Font("Arial", 12, GraphicsUnit.Point))
{
- graphics.DrawString(TextToRender, font, System.Drawing.Brushes.HotPink, new RectangleF(10, 10, 780, 780));
+ graphics.DrawString(this.TextToRender, font, System.Drawing.Brushes.HotPink, new RectangleF(10, 10, 780, 780));
}
}
}
@@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Benchmarks
using (var image = new Image(800, 800))
{
var font = SixLabors.Fonts.SystemFonts.CreateFont("Arial", 12);
- image.Mutate(x => x.ApplyProcessor(new DrawTextProcessor(new TextGraphicsOptions(true) { WrapTextWidth = 780 }, TextToRender, font, Processing.Brushes.Solid(Rgba32.HotPink), null, new SixLabors.Primitives.PointF(10, 10))));
+ image.Mutate(x => x.ApplyProcessor(new DrawTextProcessor(new TextGraphicsOptions { Antialias = true, WrapTextWidth = 780 }, this.TextToRender, font, Processing.Brushes.Solid(Rgba32.HotPink), null, new SixLabors.Primitives.PointF(10, 10))));
}
}
@@ -52,7 +52,7 @@ namespace SixLabors.ImageSharp.Benchmarks
using (var image = new Image(800, 800))
{
var font = SixLabors.Fonts.SystemFonts.CreateFont("Arial", 12);
- image.Mutate(x => DrawTextOldVersion(x, new TextGraphicsOptions(true) { WrapTextWidth = 780 }, TextToRender, font, Processing.Brushes.Solid(Rgba32.HotPink), null, new SixLabors.Primitives.PointF(10, 10)));
+ image.Mutate(x => DrawTextOldVersion(x, new TextGraphicsOptions { Antialias = true, WrapTextWidth = 780 }, this.TextToRender, font, Processing.Brushes.Solid(Rgba32.HotPink), null, new SixLabors.Primitives.PointF(10, 10)));
}
IImageProcessingContext DrawTextOldVersion(
@@ -93,4 +93,4 @@ namespace SixLabors.ImageSharp.Benchmarks
}
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/ImageSharp.Benchmarks/Drawing/DrawTextOutline.cs b/tests/ImageSharp.Benchmarks/Drawing/DrawTextOutline.cs
index c5c1ba5ac..7d8b77659 100644
--- a/tests/ImageSharp.Benchmarks/Drawing/DrawTextOutline.cs
+++ b/tests/ImageSharp.Benchmarks/Drawing/DrawTextOutline.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Drawing;
@@ -17,7 +17,7 @@ namespace SixLabors.ImageSharp.Benchmarks
[Params(10, 100)]
public int TextIterations { get; set; }
public string TextPhrase { get; set; } = "Hello World";
- public string TextToRender => string.Join(" ", Enumerable.Repeat(TextPhrase, TextIterations));
+ public string TextToRender => string.Join(" ", Enumerable.Repeat(this.TextPhrase, this.TextIterations));
[Benchmark(Baseline = true, Description = "System.Drawing Draw Text Outline")]
public void DrawTextSystemDrawing()
@@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp.Benchmarks
using (var font = new Font("Arial", 12, GraphicsUnit.Point))
using (var gp = new GraphicsPath())
{
- gp.AddString(TextToRender, font.FontFamily, (int)font.Style, font.Size, new RectangleF(10, 10, 780, 780), new StringFormat());
+ gp.AddString(this.TextToRender, font.FontFamily, (int)font.Style, font.Size, new RectangleF(10, 10, 780, 780), new StringFormat());
graphics.DrawPath(pen, gp);
}
}
@@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Benchmarks
using (var image = new Image(800, 800))
{
var font = SixLabors.Fonts.SystemFonts.CreateFont("Arial", 12);
- image.Mutate(x => x.ApplyProcessor(new DrawTextProcessor(new TextGraphicsOptions(true) { WrapTextWidth = 780 }, TextToRender, font, null, Processing.Pens.Solid(Rgba32.HotPink, 10), new SixLabors.Primitives.PointF(10, 10))));
+ image.Mutate(x => x.ApplyProcessor(new DrawTextProcessor(new TextGraphicsOptions { Antialias = true, WrapTextWidth = 780 }, this.TextToRender, font, null, Processing.Pens.Solid(Rgba32.HotPink, 10), new SixLabors.Primitives.PointF(10, 10))));
}
}
@@ -56,8 +56,8 @@ namespace SixLabors.ImageSharp.Benchmarks
image.Mutate(
x => DrawTextOldVersion(
x,
- new TextGraphicsOptions(true) { WrapTextWidth = 780 },
- TextToRender,
+ new TextGraphicsOptions { Antialias = true, WrapTextWidth = 780 },
+ this.TextToRender,
font,
null,
Processing.Pens.Solid(Rgba32.HotPink, 10),
@@ -99,4 +99,4 @@ namespace SixLabors.ImageSharp.Benchmarks
}
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/ImageSharp.Tests/Drawing/DrawImageTests.cs b/tests/ImageSharp.Tests/Drawing/DrawImageTests.cs
index 86c1c2850..61b45729d 100644
--- a/tests/ImageSharp.Tests/Drawing/DrawImageTests.cs
+++ b/tests/ImageSharp.Tests/Drawing/DrawImageTests.cs
@@ -190,7 +190,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing
void Test()
{
- background.Mutate(context => context.DrawImage(overlay, new Point(x, y), GraphicsOptions.Default));
+ background.Mutate(context => context.DrawImage(overlay, new Point(x, y), new GraphicsOptions()));
}
}
}
diff --git a/tests/ImageSharp.Tests/Drawing/DrawLinesTests.cs b/tests/ImageSharp.Tests/Drawing/DrawLinesTests.cs
index 2836f8a38..b45fc620b 100644
--- a/tests/ImageSharp.Tests/Drawing/DrawLinesTests.cs
+++ b/tests/ImageSharp.Tests/Drawing/DrawLinesTests.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@@ -24,10 +24,10 @@ namespace SixLabors.ImageSharp.Tests.Drawing
{
Color color = TestUtils.GetColorByName(colorName).WithAlpha(alpha);
Pen pen = new Pen(color, thickness);
-
+
DrawLinesImpl(provider, colorName, alpha, thickness, antialias, pen);
}
-
+
[Theory]
[WithBasicTestPatternImages(250, 350, PixelTypes.Rgba32, "White", 1f, 5, false)]
public void DrawLines_Dash(TestImageProvider provider, string colorName, float alpha, float thickness, bool antialias)
@@ -35,10 +35,10 @@ namespace SixLabors.ImageSharp.Tests.Drawing
{
Color color = TestUtils.GetColorByName(colorName).WithAlpha(alpha);
Pen pen = Pens.Dash(color, thickness);
-
+
DrawLinesImpl(provider, colorName, alpha, thickness, antialias, pen);
}
-
+
[Theory]
[WithBasicTestPatternImages(250, 350, PixelTypes.Rgba32, "LightGreen", 1f, 5, false)]
public void DrawLines_Dot(TestImageProvider provider, string colorName, float alpha, float thickness, bool antialias)
@@ -46,10 +46,10 @@ namespace SixLabors.ImageSharp.Tests.Drawing
{
Color color = TestUtils.GetColorByName(colorName).WithAlpha(alpha);
Pen pen = Pens.Dot(color, thickness);
-
+
DrawLinesImpl(provider, colorName, alpha, thickness, antialias, pen);
}
-
+
[Theory]
[WithBasicTestPatternImages(250, 350, PixelTypes.Rgba32, "Yellow", 1f, 5, false)]
public void DrawLines_DashDot(TestImageProvider provider, string colorName, float alpha, float thickness, bool antialias)
@@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing
{
Color color = TestUtils.GetColorByName(colorName).WithAlpha(alpha);
Pen pen = Pens.DashDot(color, thickness);
-
+
DrawLinesImpl(provider, colorName, alpha, thickness, antialias, pen);
}
@@ -68,11 +68,11 @@ namespace SixLabors.ImageSharp.Tests.Drawing
{
Color color = TestUtils.GetColorByName(colorName).WithAlpha(alpha);
Pen pen = Pens.DashDotDot(color, thickness);
-
+
DrawLinesImpl(provider, colorName, alpha, thickness, antialias, pen);
}
-
+
private static void DrawLinesImpl(
TestImageProvider provider,
string colorName,
@@ -84,7 +84,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing
{
SixLabors.Primitives.PointF[] simplePath = { new Vector2(10, 10), new Vector2(200, 150), new Vector2(50, 300) };
- GraphicsOptions options = new GraphicsOptions(antialias);
+ GraphicsOptions options = new GraphicsOptions { Antialias = antialias };
string aa = antialias ? "" : "_NoAntialias";
FormattableString outputDetails = $"{colorName}_A({alpha})_T({thickness}){aa}";
diff --git a/tests/ImageSharp.Tests/Drawing/DrawPolygonTests.cs b/tests/ImageSharp.Tests/Drawing/DrawPolygonTests.cs
index 18fde6ad8..4a6cb430a 100644
--- a/tests/ImageSharp.Tests/Drawing/DrawPolygonTests.cs
+++ b/tests/ImageSharp.Tests/Drawing/DrawPolygonTests.cs
@@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing
};
Color color = TestUtils.GetColorByName(colorName).WithAlpha(alpha);
- GraphicsOptions options = new GraphicsOptions(antialias);
+ GraphicsOptions options = new GraphicsOptions { Antialias = antialias };
string aa = antialias ? "" : "_NoAntialias";
FormattableString outputDetails = $"{colorName}_A({alpha})_T({thickness}){aa}";
diff --git a/tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs b/tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs
index 361e7e70d..031e732ea 100644
--- a/tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs
+++ b/tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@@ -16,6 +16,8 @@ namespace SixLabors.ImageSharp.Tests.Drawing
{
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
+ using SixLabors.Primitives;
+ using SixLabors.Shapes;
[GroupOutput("Drawing/GradientBrushes")]
public class FillLinearGradientBrushTests
@@ -392,5 +394,44 @@ namespace SixLabors.ImageSharp.Tests.Drawing
false,
false);
}
+
+ [Theory]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32)]
+ public void GradientsWithTransparencyOnExistingBackground(TestImageProvider provider)
+ where TPixel : struct, IPixel
+ {
+ provider.VerifyOperation(
+ image =>
+ {
+ image.Mutate(i => i.Fill(Color.Red));
+ image.Mutate(ApplyGloss);
+
+ });
+
+ void ApplyGloss(IImageProcessingContext ctx)
+ {
+ Size size = ctx.GetCurrentSize();
+ IPathCollection glossPath = BuildGloss(size.Width, size.Height);
+ var graphicsOptions = new GraphicsOptions
+ {
+ Antialias = true,
+ ColorBlendingMode = PixelColorBlendingMode.Normal,
+ AlphaCompositionMode = PixelAlphaCompositionMode.SrcAtop
+ };
+ var linearGradientBrush = new LinearGradientBrush(new Point(0, 0), new Point(0, size.Height / 2), GradientRepetitionMode.Repeat, new ColorStop(0, Color.White.WithAlpha(0.5f)), new ColorStop(1, Color.White.WithAlpha(0.25f)));
+ ctx.Fill(graphicsOptions, linearGradientBrush, glossPath);
+ }
+
+ IPathCollection BuildGloss(int imageWidth, int imageHeight)
+ {
+ var pathBuilder = new PathBuilder();
+ pathBuilder.AddLine(new PointF(0, 0), new PointF(imageWidth, 0));
+ pathBuilder.AddLine(new PointF(imageWidth, 0), new PointF(imageWidth, imageHeight * 0.4f));
+ pathBuilder.AddBezier(new PointF(imageWidth, imageHeight * 0.4f), new PointF(imageWidth / 2, imageHeight * 0.6f), new PointF(0, imageHeight * 0.4f));
+ pathBuilder.CloseFigure();
+ return new PathCollection(pathBuilder.Build());
+ }
+ }
+
}
-}
\ No newline at end of file
+}
diff --git a/tests/ImageSharp.Tests/Drawing/FillPolygonTests.cs b/tests/ImageSharp.Tests/Drawing/FillPolygonTests.cs
index 104237ec3..22294e76d 100644
--- a/tests/ImageSharp.Tests/Drawing/FillPolygonTests.cs
+++ b/tests/ImageSharp.Tests/Drawing/FillPolygonTests.cs
@@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing
};
Color color = TestUtils.GetColorByName(colorName).WithAlpha(alpha);
- var options = new GraphicsOptions(antialias);
+ var options = new GraphicsOptions { Antialias = antialias };
string aa = antialias ? "" : "_NoAntialias";
FormattableString outputDetails = $"{colorName}_A{alpha}{aa}";
diff --git a/tests/ImageSharp.Tests/Drawing/FillRegionProcessorTests.cs b/tests/ImageSharp.Tests/Drawing/FillRegionProcessorTests.cs
index c0388ea2d..e259d29d9 100644
--- a/tests/ImageSharp.Tests/Drawing/FillRegionProcessorTests.cs
+++ b/tests/ImageSharp.Tests/Drawing/FillRegionProcessorTests.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Numerics;
@@ -16,8 +16,6 @@ using SixLabors.Shapes;
namespace SixLabors.ImageSharp.Tests.Drawing
{
-
-
public class FillRegionProcessorTests
{
@@ -35,11 +33,12 @@ namespace SixLabors.ImageSharp.Tests.Drawing
var brush = new Mock();
var region = new MockRegion2(bounds);
- var options = new GraphicsOptions(antialias)
+ var options = new GraphicsOptions
{
+ Antialias = antialias,
AntialiasSubpixelDepth = 1
};
- var processor = new FillRegionProcessor(brush.Object, region, options);
+ var processor = new FillRegionProcessor(options, brush.Object, region);
var img = new Image(1, 1);
processor.Execute(img, bounds);
@@ -51,8 +50,8 @@ namespace SixLabors.ImageSharp.Tests.Drawing
{
var bounds = new Rectangle(-100, -10, 10, 10);
var brush = new Mock();
- var options = new GraphicsOptions(true);
- var processor = new FillRegionProcessor(brush.Object, new MockRegion1(), options);
+ var options = new GraphicsOptions { Antialias = true };
+ var processor = new FillRegionProcessor(options, brush.Object, new MockRegion1());
var img = new Image(10, 10);
processor.Execute(img, bounds);
}
@@ -73,11 +72,12 @@ namespace SixLabors.ImageSharp.Tests.Drawing
public void DoesNotThrowForIssue928()
{
var rectText = new RectangleF(0, 0, 2000, 2000);
- using (Image img = new Image((int)rectText.Width, (int)rectText.Height))
+ using (var img = new Image((int)rectText.Width, (int)rectText.Height))
{
img.Mutate(x => x.Fill(Rgba32.Transparent));
- img.Mutate(ctx => {
+ img.Mutate(ctx =>
+ {
ctx.DrawLines(
Rgba32.Red,
0.984252f,
@@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing
new PointF(104.782608f, 1075.13245f),
new PointF(104.782608f, 1075.13245f)
);
- }
+ }
);
}
}
@@ -98,7 +98,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing
[Fact]
public void DoesNotThrowFillingTriangle()
{
- using(var image = new Image(28, 28))
+ using (var image = new Image(28, 28))
{
var path = new Polygon(
new LinearLineSegment(new PointF(17.11f, 13.99659f), new PointF(14.01433f, 27.06201f)),
diff --git a/tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs b/tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs
index a5e745083..1e3688fea 100644
--- a/tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs
+++ b/tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs
@@ -156,10 +156,12 @@ namespace SixLabors.ImageSharp.Tests.Drawing
{
TPixel bgColor = image[0, 0];
- var options = new GraphicsOptions(false)
- {
- ColorBlendingMode = blenderMode, BlendPercentage = blendPercentage
- };
+ var options = new GraphicsOptions
+ {
+ Antialias = false,
+ ColorBlendingMode = blenderMode,
+ BlendPercentage = blendPercentage
+ };
if (triggerFillRegion)
{
@@ -173,13 +175,13 @@ namespace SixLabors.ImageSharp.Tests.Drawing
}
var testOutputDetails = new
- {
- triggerFillRegion = triggerFillRegion,
- newColorName = newColorName,
- alpha = alpha,
- blenderMode = blenderMode,
- blendPercentage = blendPercentage
- };
+ {
+ triggerFillRegion = triggerFillRegion,
+ newColorName = newColorName,
+ alpha = alpha,
+ blenderMode = blenderMode,
+ blendPercentage = blendPercentage
+ };
image.DebugSave(
provider,
diff --git a/tests/ImageSharp.Tests/Drawing/Paths/DrawPathCollection.cs b/tests/ImageSharp.Tests/Drawing/Paths/DrawPathCollection.cs
index 3691b54ce..36c11035c 100644
--- a/tests/ImageSharp.Tests/Drawing/Paths/DrawPathCollection.cs
+++ b/tests/ImageSharp.Tests/Drawing/Paths/DrawPathCollection.cs
@@ -7,6 +7,7 @@ using SixLabors.ImageSharp.Primitives;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Tests.Processing;
+using SixLabors.ImageSharp.Tests.TestUtilities;
using SixLabors.Shapes;
using Xunit;
@@ -14,7 +15,9 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
{
public class DrawPathCollection : BaseImageOperationsExtensionTest
{
- GraphicsOptions noneDefault = new GraphicsOptions();
+ private static readonly GraphicsOptionsComparer graphicsOptionsComparer = new GraphicsOptionsComparer();
+
+ GraphicsOptions nonDefault = new GraphicsOptions { Antialias = false };
Color color = Color.HotPink;
Pen pen = Pens.Solid(Rgba32.HotPink, 1);
IPath path1 = new Path(new LinearLineSegment(new SixLabors.Primitives.PointF[] {
@@ -46,7 +49,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
{
FillRegionProcessor processor = this.Verify(i);
- Assert.Equal(GraphicsOptions.Default, processor.Options);
+ Assert.Equal(new GraphicsOptions(), processor.Options, graphicsOptionsComparer);
ShapePath region = Assert.IsType(processor.Region);
@@ -60,13 +63,13 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsBrushPathOptions()
{
- this.operations.Draw(this.noneDefault, this.pen, this.pathCollection);
+ this.operations.Draw(this.nonDefault, this.pen, this.pathCollection);
for (int i = 0; i < 2; i++)
{
FillRegionProcessor processor = this.Verify(i);
- Assert.Equal(this.noneDefault, processor.Options);
+ Assert.Equal(this.nonDefault, processor.Options, graphicsOptionsComparer);
ShapePath region = Assert.IsType(processor.Region);
Assert.IsType(region.Shape);
@@ -84,7 +87,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
{
FillRegionProcessor processor = this.Verify(i);
- Assert.Equal(GraphicsOptions.Default, processor.Options);
+ Assert.Equal(new GraphicsOptions(), processor.Options, graphicsOptionsComparer);
ShapePath region = Assert.IsType(processor.Region);
Assert.IsType(region.Shape);
@@ -97,13 +100,13 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsColorPathAndOptions()
{
- this.operations.Draw(this.noneDefault, this.color, 1, this.pathCollection);
+ this.operations.Draw(this.nonDefault, this.color, 1, this.pathCollection);
for (int i = 0; i < 2; i++)
{
FillRegionProcessor processor = this.Verify(i);
- Assert.Equal(this.noneDefault, processor.Options);
+ Assert.Equal(this.nonDefault, processor.Options, graphicsOptionsComparer);
ShapePath region = Assert.IsType(processor.Region);
Assert.IsType(region.Shape);
diff --git a/tests/ImageSharp.Tests/Drawing/Paths/FillPath.cs b/tests/ImageSharp.Tests/Drawing/Paths/FillPath.cs
index 160ff22a3..cea59e15e 100644
--- a/tests/ImageSharp.Tests/Drawing/Paths/FillPath.cs
+++ b/tests/ImageSharp.Tests/Drawing/Paths/FillPath.cs
@@ -7,6 +7,7 @@ using SixLabors.ImageSharp.Primitives;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Tests.Processing;
+using SixLabors.ImageSharp.Tests.TestUtilities;
using SixLabors.Shapes;
using Xunit;
@@ -14,7 +15,9 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
{
public class FillPath : BaseImageOperationsExtensionTest
{
- GraphicsOptions noneDefault = new GraphicsOptions();
+ private static readonly GraphicsOptionsComparer graphicsOptionsComparer = new GraphicsOptionsComparer();
+
+ GraphicsOptions nonDefault = new GraphicsOptions { Antialias = false };
Color color = Color.HotPink;
SolidBrush brush = Brushes.Solid(Rgba32.HotPink);
IPath path = new Path(new LinearLineSegment(new SixLabors.Primitives.PointF[] {
@@ -30,7 +33,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
this.operations.Fill(this.brush, this.path);
var processor = this.Verify();
- Assert.Equal(GraphicsOptions.Default, processor.Options);
+ Assert.Equal(new GraphicsOptions(), processor.Options, graphicsOptionsComparer);
ShapeRegion region = Assert.IsType(processor.Region);
@@ -44,10 +47,10 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsBrushPathOptions()
{
- this.operations.Fill(this.noneDefault, this.brush, this.path);
+ this.operations.Fill(this.nonDefault, this.brush, this.path);
var processor = this.Verify();
- Assert.Equal(this.noneDefault, processor.Options);
+ Assert.Equal(this.nonDefault, processor.Options, graphicsOptionsComparer);
ShapeRegion region = Assert.IsType(processor.Region);
Polygon polygon = Assert.IsType(region.Shape);
@@ -62,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
this.operations.Fill(this.color, this.path);
var processor = this.Verify();
- Assert.Equal(GraphicsOptions.Default, processor.Options);
+ Assert.Equal(new GraphicsOptions(), processor.Options, graphicsOptionsComparer);
ShapeRegion region = Assert.IsType(processor.Region);
Polygon polygon = Assert.IsType(region.Shape);
@@ -75,10 +78,10 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsColorPathAndOptions()
{
- this.operations.Fill(this.noneDefault, this.color, this.path);
+ this.operations.Fill(this.nonDefault, this.color, this.path);
var processor = this.Verify();
- Assert.Equal(this.noneDefault, processor.Options);
+ Assert.Equal(this.nonDefault, processor.Options);
ShapeRegion region = Assert.IsType(processor.Region);
Polygon polygon = Assert.IsType(region.Shape);
diff --git a/tests/ImageSharp.Tests/Drawing/Paths/FillPathCollection.cs b/tests/ImageSharp.Tests/Drawing/Paths/FillPathCollection.cs
index b76ee8ffc..2a9c04a89 100644
--- a/tests/ImageSharp.Tests/Drawing/Paths/FillPathCollection.cs
+++ b/tests/ImageSharp.Tests/Drawing/Paths/FillPathCollection.cs
@@ -7,6 +7,7 @@ using SixLabors.ImageSharp.Primitives;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Drawing;
using SixLabors.ImageSharp.Tests.Processing;
+using SixLabors.ImageSharp.Tests.TestUtilities;
using SixLabors.Shapes;
using Xunit;
@@ -14,7 +15,9 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
{
public class FillPathCollection : BaseImageOperationsExtensionTest
{
- GraphicsOptions noneDefault = new GraphicsOptions();
+ private static readonly GraphicsOptionsComparer graphicsOptionsComparer = new GraphicsOptionsComparer();
+
+ GraphicsOptions nonDefault = new GraphicsOptions { Antialias = false };
Color color = Color.HotPink;
SolidBrush brush = Brushes.Solid(Rgba32.HotPink);
IPath path1 = new Path(new LinearLineSegment(new SixLabors.Primitives.PointF[] {
@@ -46,7 +49,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
{
FillRegionProcessor processor = this.Verify(i);
- Assert.Equal(GraphicsOptions.Default, processor.Options);
+ Assert.Equal(new GraphicsOptions(), processor.Options, graphicsOptionsComparer);
ShapeRegion region = Assert.IsType(processor.Region);
@@ -61,13 +64,13 @@ namespace SixLabors.ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsBrushPathOptions()
{
- this.operations.Fill(this.noneDefault, this.brush, this.pathCollection);
+ this.operations.Fill(this.nonDefault, this.brush, this.pathCollection);
for (int i = 0; i < 2; i++)
{
FillRegionProcessor processor = this.Verify(i);
- Assert.Equal(this.noneDefault, processor.Options);
+ Assert.Equal(this.nonDefault, processor.Options, graphicsOptionsComparer);
ShapeRegion region = Assert.IsType(processor.Region);
Polygon polygon = Assert.IsType