diff --git a/src/ImageSharp.Drawing/Processing/Brushes.cs b/src/ImageSharp.Drawing/Processing/Brushes.cs index c5e7a3e9f..bd73e1f1b 100644 --- a/src/ImageSharp.Drawing/Processing/Brushes.cs +++ b/src/ImageSharp.Drawing/Processing/Brushes.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Processing /// /// A collection of methods for creating generic brushes. /// - /// A New + /// A New public static class Brushes { /// @@ -94,163 +94,131 @@ namespace SixLabors.ImageSharp.Processing /// Create as brush that will paint a solid color /// /// The color. - /// The pixel format. - /// A New - public static SolidBrush Solid(TPixel color) - where TPixel : struct, IPixel - => new SolidBrush(color); + /// A New + public static SolidBrush Solid(Color color) => new SolidBrush(color); /// /// Create as brush that will paint a Percent10 Hatch Pattern with the specified colors /// /// Color of the foreground. - /// The pixel format. - /// A New - public static PatternBrush Percent10(TPixel foreColor) - where TPixel : struct, IPixel - => new PatternBrush(foreColor, NamedColors.Transparent, Percent10Pattern); + /// A New + public static PatternBrush Percent10(Color foreColor) => + new PatternBrush(foreColor, Color.Transparent, Percent10Pattern); /// /// Create as brush that will paint a Percent10 Hatch Pattern with the specified colors /// /// Color of the foreground. /// Color of the background. - /// The pixel format. - /// A New - public static PatternBrush Percent10(TPixel foreColor, TPixel backColor) - where TPixel : struct, IPixel - => new PatternBrush(foreColor, backColor, Percent10Pattern); + /// A New + public static PatternBrush Percent10(Color foreColor, Color backColor) => + new PatternBrush(foreColor, backColor, Percent10Pattern); /// /// Create as brush that will paint a Percent20 Hatch Pattern with the specified foreground color and a /// transparent background. /// /// Color of the foreground. - /// The pixel format. - /// A New - public static PatternBrush Percent20(TPixel foreColor) - where TPixel : struct, IPixel - => new PatternBrush(foreColor, NamedColors.Transparent, Percent20Pattern); + /// A New + public static PatternBrush Percent20(Color foreColor) => + new PatternBrush(foreColor, Color.Transparent, Percent20Pattern); /// /// Create as brush that will paint a Percent20 Hatch Pattern with the specified colors /// /// Color of the foreground. /// Color of the background. - /// The pixel format. - /// A New - public static PatternBrush Percent20(TPixel foreColor, TPixel backColor) - where TPixel : struct, IPixel - => new PatternBrush(foreColor, backColor, Percent20Pattern); + /// A New + public static PatternBrush Percent20(Color foreColor, Color backColor) => + new PatternBrush(foreColor, backColor, Percent20Pattern); /// /// Create as brush that will paint a Horizontal Hatch Pattern with the specified foreground color and a /// transparent background. /// /// Color of the foreground. - /// The pixel format. - /// A New - public static PatternBrush Horizontal(TPixel foreColor) - where TPixel : struct, IPixel - => new PatternBrush(foreColor, NamedColors.Transparent, HorizontalPattern); + /// A New + public static PatternBrush Horizontal(Color foreColor) => + new PatternBrush(foreColor, Color.Transparent, HorizontalPattern); /// /// Create as brush that will paint a Horizontal Hatch Pattern with the specified colors /// /// Color of the foreground. /// Color of the background. - /// The pixel format. - /// A New - public static PatternBrush Horizontal(TPixel foreColor, TPixel backColor) - where TPixel : struct, IPixel - => new PatternBrush(foreColor, backColor, HorizontalPattern); + /// A New + public static PatternBrush Horizontal(Color foreColor, Color backColor) => + new PatternBrush(foreColor, backColor, HorizontalPattern); /// /// Create as brush that will paint a Min Hatch Pattern with the specified foreground color and a /// transparent background. /// /// Color of the foreground. - /// The pixel format. - /// A New - public static PatternBrush Min(TPixel foreColor) - where TPixel : struct, IPixel - => new PatternBrush(foreColor, NamedColors.Transparent, MinPattern); + /// A New + public static PatternBrush Min(Color foreColor) => new PatternBrush(foreColor, Color.Transparent, MinPattern); /// /// Create as brush that will paint a Min Hatch Pattern with the specified colors /// /// Color of the foreground. /// Color of the background. - /// The pixel format. - /// A New - public static PatternBrush Min(TPixel foreColor, TPixel backColor) - where TPixel : struct, IPixel - => new PatternBrush(foreColor, backColor, MinPattern); + /// A New + public static PatternBrush Min(Color foreColor, Color backColor) => + new PatternBrush(foreColor, backColor, MinPattern); /// /// Create as brush that will paint a Vertical Hatch Pattern with the specified foreground color and a /// transparent background. /// /// Color of the foreground. - /// The pixel format. - /// A New - public static PatternBrush Vertical(TPixel foreColor) - where TPixel : struct, IPixel - => new PatternBrush(foreColor, NamedColors.Transparent, VerticalPattern); + /// A New + public static PatternBrush Vertical(Color foreColor) => + new PatternBrush(foreColor, Color.Transparent, VerticalPattern); /// /// Create as brush that will paint a Vertical Hatch Pattern with the specified colors /// /// Color of the foreground. /// Color of the background. - /// The pixel format. - /// A New - public static PatternBrush Vertical(TPixel foreColor, TPixel backColor) - where TPixel : struct, IPixel - => new PatternBrush(foreColor, backColor, VerticalPattern); + /// A New + public static PatternBrush Vertical(Color foreColor, Color backColor) => + new PatternBrush(foreColor, backColor, VerticalPattern); /// /// Create as brush that will paint a Forward Diagonal Hatch Pattern with the specified foreground color and a /// transparent background. /// /// Color of the foreground. - /// The pixel format. - /// A New - public static PatternBrush ForwardDiagonal(TPixel foreColor) - where TPixel : struct, IPixel - => new PatternBrush(foreColor, NamedColors.Transparent, ForwardDiagonalPattern); + /// A New + public static PatternBrush ForwardDiagonal(Color foreColor) => + new PatternBrush(foreColor, Color.Transparent, ForwardDiagonalPattern); /// /// Create as brush that will paint a Forward Diagonal Hatch Pattern with the specified colors /// /// Color of the foreground. /// Color of the background. - /// The pixel format. - /// A New - public static PatternBrush ForwardDiagonal(TPixel foreColor, TPixel backColor) - where TPixel : struct, IPixel - => new PatternBrush(foreColor, backColor, ForwardDiagonalPattern); + /// A New + public static PatternBrush ForwardDiagonal(Color foreColor, Color backColor) => + new PatternBrush(foreColor, backColor, ForwardDiagonalPattern); /// /// Create as brush that will paint a Backward Diagonal Hatch Pattern with the specified foreground color and a /// transparent background. /// /// Color of the foreground. - /// The pixel format. - /// A New - public static PatternBrush BackwardDiagonal(TPixel foreColor) - where TPixel : struct, IPixel - => new PatternBrush(foreColor, NamedColors.Transparent, BackwardDiagonalPattern); + /// A New + public static PatternBrush BackwardDiagonal(Color foreColor) => + new PatternBrush(foreColor, Color.Transparent, BackwardDiagonalPattern); /// /// Create as brush that will paint a Backward Diagonal Hatch Pattern with the specified colors /// /// Color of the foreground. /// Color of the background. - /// The pixel format. - /// A New - public static PatternBrush BackwardDiagonal(TPixel foreColor, TPixel backColor) - where TPixel : struct, IPixel - => new PatternBrush(foreColor, backColor, BackwardDiagonalPattern); + /// A New + public static PatternBrush BackwardDiagonal(Color foreColor, Color backColor) => + new PatternBrush(foreColor, backColor, BackwardDiagonalPattern); } } \ No newline at end of file diff --git a/src/ImageSharp.Drawing/Processing/DrawBezierExtensions.cs b/src/ImageSharp.Drawing/Processing/DrawBezierExtensions.cs index 782f5d4d7..991c01293 100644 --- a/src/ImageSharp.Drawing/Processing/DrawBezierExtensions.cs +++ b/src/ImageSharp.Drawing/Processing/DrawBezierExtensions.cs @@ -15,80 +15,80 @@ namespace SixLabors.ImageSharp.Processing /// /// Draws the provided points as an open Bezier path at the provided thickness with the supplied brush /// - /// The type of the color. + /// The image this method extends. /// The options. /// The brush. /// The thickness. /// The points. /// The . - public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, GraphicsOptions options, IBrush brush, float thickness, params PointF[] points) - where TPixel : struct, IPixel - => source.Draw(options, new Pen(brush, thickness), new Path(new CubicBezierLineSegment(points))); + public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, GraphicsOptions options, IBrush brush, float thickness, params PointF[] points) + + => source.Draw(options, new Pen(brush, thickness), new Path(new CubicBezierLineSegment(points))); /// /// Draws the provided points as an open Bezier path at the provided thickness with the supplied brush /// - /// The type of the color. + /// The image this method extends. /// The brush. /// The thickness. /// The points. /// The . - public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, IBrush brush, float thickness, params PointF[] points) - where TPixel : struct, IPixel - => source.Draw(new Pen(brush, thickness), new Path(new CubicBezierLineSegment(points))); + public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, IBrush brush, float thickness, params PointF[] points) + + => source.Draw(new Pen(brush, thickness), new Path(new CubicBezierLineSegment(points))); /// /// Draws the provided points as an open Bezier path at the provided thickness with the supplied brush /// - /// The type of the color. + /// The image this method extends. /// The color. /// The thickness. /// The points. /// The . - public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, TPixel color, float thickness, params PointF[] points) - where TPixel : struct, IPixel - => source.DrawBeziers(new SolidBrush(color), thickness, points); + public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, TPixel color, float thickness, params PointF[] points) + + => source.DrawBeziers(new SolidBrush(color), thickness, points); /// /// Draws the provided points as an open Bezier path at the provided thickness with the supplied brush /// - /// The type of the color. + /// The image this method extends. /// The options. /// The color. /// The thickness. /// The points. /// The . - public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, GraphicsOptions options, TPixel color, float thickness, params PointF[] points) - where TPixel : struct, IPixel - => source.DrawBeziers(options, new SolidBrush(color), thickness, points); + public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, GraphicsOptions options, TPixel color, float thickness, params PointF[] points) + + => source.DrawBeziers(options, new SolidBrush(color), thickness, points); /// /// Draws the provided points as an open Bezier path with the supplied pen /// - /// The type of the color. + /// The image this method extends. /// The options. /// The pen. /// The points. /// The . - public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, GraphicsOptions options, IPen pen, params PointF[] points) - where TPixel : struct, IPixel + public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, GraphicsOptions options, IPen pen, params PointF[] points) + => source.Draw(options, pen, new Path(new CubicBezierLineSegment(points))); /// /// Draws the provided points as an open Bezier path with the supplied pen /// - /// The type of the color. + /// The image this method extends. /// The pen. /// The points. /// The . - public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, IPen pen, params PointF[] points) - where TPixel : struct, IPixel + public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, IPen pen, params PointF[] points) + => source.Draw(pen, new Path(new CubicBezierLineSegment(points))); } } diff --git a/src/ImageSharp.Drawing/Processing/ImageBrush{TPixel}.cs b/src/ImageSharp.Drawing/Processing/ImageBrush{TPixel}.cs index cfb3b2ea4..d5ec1123d 100644 --- a/src/ImageSharp.Drawing/Processing/ImageBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Processing/ImageBrush{TPixel}.cs @@ -15,40 +15,38 @@ namespace SixLabors.ImageSharp.Processing /// Provides an implementation of an image brush for painting images within areas. /// /// The pixel format. - public class ImageBrush : IBrush - where TPixel : struct, IPixel + public class ImageBrush : IBrush { /// /// The image to paint. /// - private readonly ImageFrame image; + private readonly Image image; /// /// Initializes a new instance of the class. /// /// The image. - public ImageBrush(ImageFrame image) + public ImageBrush(Image image) { this.image = image; } - /// - /// Initializes a new instance of the class. - /// - /// The image. - public ImageBrush(Image image) - : this(image.Frames.RootFrame) + /// + public BrushApplicator CreateApplicator( + ImageFrame source, + RectangleF region, + GraphicsOptions options) + where TPixel : struct, IPixel { + Image specificImage = (Image)this.image; + return new ImageBrushApplicator(source, specificImage.Frames.RootFrame, region, options); } - /// - public BrushApplicator CreateApplicator(ImageFrame source, RectangleF region, GraphicsOptions options) - => new ImageBrushApplicator(source, this.image, region, options); - /// /// The image brush applicator. /// - private class ImageBrushApplicator : BrushApplicator + private class ImageBrushApplicator : BrushApplicator + where TPixel : struct, IPixel { /// /// The source image. diff --git a/src/ImageSharp.Drawing/Processing/PatternBrush{TPixel}.cs b/src/ImageSharp.Drawing/Processing/PatternBrush{TPixel}.cs index 249383f3b..0e6675672 100644 --- a/src/ImageSharp.Drawing/Processing/PatternBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Processing/PatternBrush{TPixel}.cs @@ -97,7 +97,11 @@ namespace SixLabors.ImageSharp.Processing RectangleF region, GraphicsOptions options) where TPixel : struct, IPixel => - new PatternBrushApplicator(source, this.pattern, this.patternVector, options); + new PatternBrushApplicator( + source, + this.pattern.ToPixelMatrix(source.Configuration), + this.patternVector, + options); /// /// The pattern brush applicator. @@ -118,11 +122,10 @@ namespace SixLabors.ImageSharp.Processing /// The pattern. /// The patternVector. /// The options - public PatternBrushApplicator(ImageFrame source, in DenseMatrix pattern, DenseMatrix patternVector, GraphicsOptions options) + public PatternBrushApplicator(ImageFrame source, in DenseMatrix pattern, DenseMatrix patternVector, GraphicsOptions options) : base(source, options) { - this.pattern = new DenseMatrix(pattern.Columns, pattern.Rows); - Color.ToPixel(source.Configuration, pattern.Data, this.pattern.Data); + this.pattern = pattern; this.patternVector = patternVector; } diff --git a/src/ImageSharp.Drawing/Processing/Pens.cs b/src/ImageSharp.Drawing/Processing/Pens.cs index 90253a3cb..4b8f478c9 100644 --- a/src/ImageSharp.Drawing/Processing/Pens.cs +++ b/src/ImageSharp.Drawing/Processing/Pens.cs @@ -21,109 +21,79 @@ namespace SixLabors.ImageSharp.Processing /// /// The color. /// The width. - /// The type of the color. /// The Pen - public static Pen Solid(TPixel color, float width) - where TPixel : struct, IPixel - => new Pen(color, width); + public static Pen Solid(Color color, float width) => new Pen(color, width); /// /// Create a solid pen with out any drawing patterns /// /// The brush. /// The width. - /// The type of the color. /// The Pen - public static Pen Solid(IBrush brush, float width) - where TPixel : struct, IPixel - => new Pen(brush, width); + public static Pen Solid(IBrush brush, float width) => new Pen(brush, width); /// /// Create a pen with a 'Dash' drawing patterns /// /// The color. /// The width. - /// The type of the color. /// The Pen - public static Pen Dash(TPixel color, float width) - where TPixel : struct, IPixel - => new Pen(color, width, DashedPattern); + public static Pen Dash(Color color, float width) => new Pen(color, width, DashedPattern); /// /// Create a pen with a 'Dash' drawing patterns /// /// The brush. /// The width. - /// The type of the color. /// The Pen - public static Pen Dash(IBrush brush, float width) - where TPixel : struct, IPixel - => new Pen(brush, width, DashedPattern); + public static Pen Dash(IBrush brush, float width) => new Pen(brush, width, DashedPattern); /// /// Create a pen with a 'Dot' drawing patterns /// /// The color. /// The width. - /// The type of the color. /// The Pen - public static Pen Dot(TPixel color, float width) - where TPixel : struct, IPixel - => new Pen(color, width, DottedPattern); + public static Pen Dot(Color color, float width) => new Pen(color, width, DottedPattern); /// /// Create a pen with a 'Dot' drawing patterns /// /// The brush. /// The width. - /// The type of the color. /// The Pen - public static Pen Dot(IBrush brush, float width) - where TPixel : struct, IPixel - => new Pen(brush, width, DottedPattern); + public static Pen Dot(IBrush brush, float width) => new Pen(brush, width, DottedPattern); /// /// Create a pen with a 'Dash Dot' drawing patterns /// /// The color. /// The width. - /// The type of the color. /// The Pen - public static Pen DashDot(TPixel color, float width) - where TPixel : struct, IPixel - => new Pen(color, width, DashDotPattern); + public static Pen DashDot(Color color, float width) => new Pen(color, width, DashDotPattern); /// /// Create a pen with a 'Dash Dot' drawing patterns /// /// The brush. /// The width. - /// The type of the color. /// The Pen - public static Pen DashDot(IBrush brush, float width) - where TPixel : struct, IPixel - => new Pen(brush, width, DashDotPattern); + public static Pen DashDot(IBrush brush, float width) => new Pen(brush, width, DashDotPattern); /// /// Create a pen with a 'Dash Dot Dot' drawing patterns /// /// The color. /// The width. - /// The type of the color. /// The Pen - public static Pen DashDotDot(TPixel color, float width) - where TPixel : struct, IPixel - => new Pen(color, width, DashDotDotPattern); + public static Pen DashDotDot(Color color, float width) => new Pen(color, width, DashDotDotPattern); /// /// Create a pen with a 'Dash Dot Dot' drawing patterns /// /// The brush. /// The width. - /// The type of the color. /// The Pen - public static Pen DashDotDot(IBrush brush, float width) - where TPixel : struct, IPixel - => new Pen(brush, width, DashDotDotPattern); + public static Pen DashDotDot(IBrush brush, float width) => new Pen(brush, width, DashDotDotPattern); } } \ No newline at end of file diff --git a/src/ImageSharp.Drawing/Processing/Pen{TPixel}.cs b/src/ImageSharp.Drawing/Processing/Pen{TPixel}.cs index 26c21a0e5..922394946 100644 --- a/src/ImageSharp.Drawing/Processing/Pen{TPixel}.cs +++ b/src/ImageSharp.Drawing/Processing/Pen{TPixel}.cs @@ -9,7 +9,6 @@ namespace SixLabors.ImageSharp.Processing /// /// Provides a pen that can apply a pattern to a line with a set brush and thickness /// - /// The type of the color. /// /// The pattern will be in to the form of new float[]{ 1f, 2f, 0.5f} this will be /// converted into a pattern that is 3.5 times longer that the width with 3 sections @@ -18,8 +17,7 @@ namespace SixLabors.ImageSharp.Processing /// section 3 will be width/2 long and will be filled /// the the pattern will immediately repeat without gap. /// - public class Pen : IPen - where TPixel : struct, IPixel + public class Pen : IPen { private readonly float[] pattern; @@ -29,8 +27,8 @@ namespace SixLabors.ImageSharp.Processing /// The color. /// The width. /// The pattern. - public Pen(TPixel color, float width, float[] pattern) - : this(new SolidBrush(color), width, pattern) + public Pen(Color color, float width, float[] pattern) + : this(new SolidBrush(color), width, pattern) { } @@ -40,7 +38,7 @@ namespace SixLabors.ImageSharp.Processing /// The brush. /// The width. /// The pattern. - public Pen(IBrush brush, float width, float[] pattern) + public Pen(IBrush brush, float width, float[] pattern) { this.StrokeFill = brush; this.StrokeWidth = width; @@ -52,8 +50,8 @@ namespace SixLabors.ImageSharp.Processing /// /// The color. /// The width. - public Pen(TPixel color, float width) - : this(new SolidBrush(color), width) + public Pen(Color color, float width) + : this(new SolidBrush(color), width) { } @@ -62,13 +60,13 @@ namespace SixLabors.ImageSharp.Processing /// /// The brush. /// The width. - public Pen(IBrush brush, float width) + public Pen(IBrush brush, float width) : this(brush, width, Pens.EmptyPattern) { } /// - public IBrush StrokeFill { get; } + public IBrush StrokeFill { get; } /// public float StrokeWidth { get; } diff --git a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor.cs index ed6c86951..8ea1c48cc 100644 --- a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor.cs +++ b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillProcessor.cs @@ -13,6 +13,26 @@ using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Drawing { + public class FillProcessor : IImageProcessor + { + public FillProcessor(IBrush brush, GraphicsOptions options) + { + this.Brush = brush; + this.Options = options; + } + + public IBrush Brush { get; } + + public GraphicsOptions Options { get; } + + /// + public IImageProcessor CreatePixelSpecificProcessor() + where TPixel : struct, IPixel + { + return new FillProcessor(this); + } + } + /// /// Using the brush as a source of pixels colors blends the brush color with source. /// @@ -20,21 +40,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing internal class FillProcessor : ImageProcessor where TPixel : struct, IPixel { - /// - /// The brush. - /// - private readonly IBrush brush; - private readonly GraphicsOptions options; - - /// - /// Initializes a new instance of the class. - /// - /// The brush to source pixel colors from. - /// The options - public FillProcessor(IBrush brush, GraphicsOptions options) + private readonly FillProcessor definition; + + public FillProcessor(FillProcessor definition) { - this.brush = brush; - this.options = options; + this.definition = definition; } /// @@ -55,11 +65,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY); + IBrush brush = this.definition.Brush; + GraphicsOptions options = this.definition.Options; + // If there's no reason for blending, then avoid it. - if (this.IsSolidBrushWithoutBlending(out SolidBrush solidBrush)) + if (this.IsSolidBrushWithoutBlending(out SolidBrush solidBrush)) { ParallelExecutionSettings parallelSettings = configuration.GetParallelSettings().MultiplyMinimumPixelsPerTask(4); + TPixel colorPixel = solidBrush.Color.ToPixel(); + ParallelHelper.IterateRows( workingRect, parallelSettings, @@ -67,7 +82,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing { for (int y = rows.Min; y < rows.Max; y++) { - source.GetPixelRowSpan(y).Slice(minX, width).Fill(solidBrush.Color); + source.GetPixelRowSpan(y).Slice(minX, width).Fill(colorPixel); } }); } @@ -85,10 +100,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing } using (IMemoryOwner amount = source.MemoryAllocator.Allocate(width)) - using (BrushApplicator applicator = this.brush.CreateApplicator( + using (BrushApplicator applicator = brush.CreateApplicator( source, sourceRectangle, - this.options)) + options)) { amount.GetSpan().Fill(1f); @@ -109,16 +124,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing } } - private bool IsSolidBrushWithoutBlending(out SolidBrush solidBrush) + private bool IsSolidBrushWithoutBlending(out SolidBrush solidBrush) { - solidBrush = this.brush as SolidBrush; + solidBrush = this.definition.Brush as SolidBrush; if (solidBrush == null) { return false; } - return this.options.IsOpaqueColorWithoutBlending(solidBrush.Color); + return this.definition.Options.IsOpaqueColorWithoutBlending(solidBrush.Color); } } } \ No newline at end of file diff --git a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs index 550c021ca..3653102ef 100644 --- a/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs +++ b/src/ImageSharp.Drawing/Processing/Processors/Drawing/FillRegionProcessor.cs @@ -13,24 +13,15 @@ using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Drawing { - /// - /// Using a brush and a shape fills shape with contents of brush the - /// - /// The type of the color. - /// - internal class FillRegionProcessor : ImageProcessor - where TPixel : struct, IPixel + public class FillRegionProcessor : IImageProcessor { - private const float AntialiasFactor = 1f; - private const int DrawPadding = 1; - /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// 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(IBrush brush, Region region, GraphicsOptions options) { this.Region = region; this.Brush = brush; @@ -40,7 +31,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing /// /// Gets the brush. /// - public IBrush Brush { get; } + public IBrush Brush { get; } /// /// Gets the region that this processor applies to. @@ -55,10 +46,35 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing /// public GraphicsOptions Options { get; } + /// + public IImageProcessor CreatePixelSpecificProcessor() + where TPixel : struct, IPixel + { + return new FillRegionProcessor(this); + } + } + + /// + /// Using a brush and a shape fills shape with contents of brush the + /// + /// The type of the color. + /// + internal class FillRegionProcessor : ImageProcessor + where TPixel : struct, IPixel + { + private readonly FillRegionProcessor definition; + + public FillRegionProcessor(FillRegionProcessor definition) + { + this.definition = definition; + } + /// protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) { - Region region = this.Region; + GraphicsOptions options = this.definition.Options; + IBrush brush = this.definition.Brush; + Region region = this.definition.Region; Rectangle rect = region.Bounds; // Align start/end positions. @@ -84,17 +100,17 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing // and this can cause missed fills when not using antialiasing.so we offset the pixel grid by 0.5 in the x & y direction thus causing the# // region to align with the pixel grid. float offset = 0.5f; - if (this.Options.Antialias) + if (options.Antialias) { offset = 0f; // we are antialiasing skip offsetting as real antialiasing should take care of offset. - subpixelCount = this.Options.AntialiasSubpixelDepth; + subpixelCount = options.AntialiasSubpixelDepth; if (subpixelCount < 4) { subpixelCount = 4; } } - using (BrushApplicator applicator = this.Brush.CreateApplicator(source, rect, this.Options)) + using (BrushApplicator applicator = brush.CreateApplicator(source, rect, options)) { int scanlineWidth = maxX - minX; using (IMemoryOwner bBuffer = source.MemoryAllocator.Allocate(maxIntersections)) @@ -107,7 +123,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing Span buffer = bBuffer.GetSpan(); Span scanline = bScanline.GetSpan(); - bool isSolidBrushWithoutBlending = this.IsSolidBrushWithoutBlending(out SolidBrush solidBrush); + bool isSolidBrushWithoutBlending = this.IsSolidBrushWithoutBlending(out SolidBrush solidBrush); + TPixel solidBrushColor = isSolidBrushWithoutBlending ? solidBrush.Color.ToPixel() : default; for (int y = minY; y < maxY; y++) { @@ -168,7 +185,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing if (scanlineDirty) { - if (!this.Options.Antialias) + if (!options.Antialias) { bool hasOnes = false; bool hasZeros = false; @@ -190,7 +207,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing { if (hasOnes) { - source.GetPixelRowSpan(y).Slice(minX, scanlineWidth).Fill(solidBrush.Color); + source.GetPixelRowSpan(y).Slice(minX, scanlineWidth).Fill(solidBrushColor); } continue; @@ -204,16 +221,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing } } - private bool IsSolidBrushWithoutBlending(out SolidBrush solidBrush) + private bool IsSolidBrushWithoutBlending(out SolidBrush solidBrush) { - solidBrush = this.Brush as SolidBrush; + solidBrush = this.definition.Brush as SolidBrush; if (solidBrush == null) { return false; } - return this.Options.IsOpaqueColorWithoutBlending(solidBrush.Color); + return this.definition.Options.IsOpaqueColorWithoutBlending(solidBrush.Color); } } } \ No newline at end of file diff --git a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs index 266d842bf..016cf56de 100644 --- a/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs +++ b/src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs @@ -15,17 +15,10 @@ using SixLabors.Shapes; namespace SixLabors.ImageSharp.Processing.Processors.Text { - /// - /// Using the brush as a source of pixels colors blends the brush color with source. - /// - /// The pixel format. - internal class DrawTextProcessor : ImageProcessor - where TPixel : struct, IPixel + public class DrawTextProcessor : IImageProcessor { - private CachingGlyphRenderer textRenderer; - /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The options /// The text we want to render @@ -33,7 +26,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text /// The brush to source pixel colors from. /// The pen to outline text with. /// The location on the image to start drawing the text from. - public DrawTextProcessor(TextGraphicsOptions options, string text, Font font, IBrush brush, IPen pen, PointF location) + public DrawTextProcessor(TextGraphicsOptions options, string text, Font font, IBrush brush, IPen pen, PointF location) { Guard.NotNull(text, nameof(text)); Guard.NotNull(font, nameof(font)); @@ -54,7 +47,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text /// /// Gets the brush. /// - public IBrush Brush { get; } + public IBrush Brush { get; } /// /// Gets the options @@ -69,7 +62,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text /// /// Gets the pen used for outlining the text, if Null then we will not outline /// - public IPen Pen { get; } + public IPen Pen { get; } /// /// Gets the font used to render the text. @@ -81,6 +74,42 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text /// public PointF Location { get; } + /// + public IImageProcessor CreatePixelSpecificProcessor() + where TPixel : struct, IPixel + { + throw new NotImplementedException(); + } + } + + /// + /// Using the brush as a source of pixels colors blends the brush color with source. + /// + /// The pixel format. + internal class DrawTextProcessor : ImageProcessor + where TPixel : struct, IPixel + { + private CachingGlyphRenderer textRenderer; + + private readonly DrawTextProcessor definition; + + public DrawTextProcessor(DrawTextProcessor definition) + { + this.definition = definition; + } + + private TextGraphicsOptions Options => this.definition.Options; + + private Font Font => this.definition.Font; + + private PointF Location => this.definition.Location; + + private string Text => this.definition.Text; + + private IPen Pen => this.definition.Pen; + + private IBrush Brush => this.definition.Brush; + protected override void BeforeImageApply(Image source, Rectangle sourceRectangle) { base.BeforeImageApply(source, sourceRectangle); @@ -115,7 +144,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text Draw(this.textRenderer.FillOperations, this.Brush); Draw(this.textRenderer.OutlineOperations, this.Pen?.StrokeFill); - void Draw(List operations, IBrush brush) + void Draw(List operations, IBrush brush) { if (operations?.Count > 0) { diff --git a/src/ImageSharp.Drawing/Processing/RecolorBrush{TPixel}.cs b/src/ImageSharp.Drawing/Processing/RecolorBrush{TPixel}.cs index 09a1ff71f..ff098dce7 100644 --- a/src/ImageSharp.Drawing/Processing/RecolorBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Processing/RecolorBrush{TPixel}.cs @@ -16,16 +16,15 @@ namespace SixLabors.ImageSharp.Processing /// Provides an implementation of a brush that can recolor an image /// /// The pixel format. - public class RecolorBrush : IBrush - where TPixel : struct, IPixel + public class RecolorBrush : IBrush { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Color of the source. /// Color of the target. /// The threshold as a value between 0 and 1. - public RecolorBrush(TPixel sourceColor, TPixel targetColor, float threshold) + public RecolorBrush(Color sourceColor, Color targetColor, float threshold) { this.SourceColor = sourceColor; this.Threshold = threshold; @@ -43,23 +42,33 @@ namespace SixLabors.ImageSharp.Processing /// /// The color of the source. /// - public TPixel SourceColor { get; } + public Color SourceColor { get; } /// /// Gets the target color. /// - public TPixel TargetColor { get; } + public Color TargetColor { get; } /// - public BrushApplicator CreateApplicator(ImageFrame source, RectangleF region, GraphicsOptions options) + public BrushApplicator CreateApplicator( + ImageFrame source, + RectangleF region, + GraphicsOptions options) + where TPixel : struct, IPixel { - return new RecolorBrushApplicator(source, this.SourceColor, this.TargetColor, this.Threshold, options); + return new RecolorBrushApplicator( + source, + this.SourceColor.ToPixel(), + this.TargetColor.ToPixel(), + this.Threshold, + options); } /// /// The recolor brush applicator. /// - private class RecolorBrushApplicator : BrushApplicator + private class RecolorBrushApplicator : BrushApplicator + where TPixel : struct, IPixel { /// /// The source color. @@ -79,7 +88,7 @@ namespace SixLabors.ImageSharp.Processing private readonly TPixel targetColorPixel; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The source image. /// Color of the source. diff --git a/src/ImageSharp/GraphicsOptions.cs b/src/ImageSharp/GraphicsOptions.cs index 2d20c1773..537418de2 100644 --- a/src/ImageSharp/GraphicsOptions.cs +++ b/src/ImageSharp/GraphicsOptions.cs @@ -1,141 +1,141 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -using SixLabors.ImageSharp.PixelFormats; - -namespace SixLabors.ImageSharp -{ - /// - /// Options for influencing the drawing functions. - /// - public struct GraphicsOptions - { - /// - /// Represents the default . - /// - public static readonly GraphicsOptions Default = new GraphicsOptions(true); - - private float? blendPercentage; - - private int? antialiasSubpixelDepth; - - private bool? antialias; - +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp +{ + /// + /// Options for influencing the drawing functions. + /// + public struct GraphicsOptions + { + /// + /// 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) - { + 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; + this.alphaCompositionMode = PixelAlphaCompositionMode.SrcOver; + this.blendPercentage = 1; + this.antialiasSubpixelDepth = 16; + this.antialias = enableAntialiasing; } - /// - /// Initializes a new instance of the struct. - /// + /// + /// 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) + /// 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; + this.alphaCompositionMode = PixelAlphaCompositionMode.SrcOver; + this.blendPercentage = opacity; + this.antialiasSubpixelDepth = 16; + this.antialias = enableAntialiasing; } - /// - /// Initializes a new instance of the struct. - /// + /// + /// 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 - public GraphicsOptions(bool enableAntialiasing, PixelColorBlendingMode blending, float opacity) + /// color blending mode to apply to the drawing operation + public GraphicsOptions(bool enableAntialiasing, PixelColorBlendingMode blending, float opacity) { Guard.MustBeBetweenOrEqualTo(opacity, 0, 1, nameof(opacity)); - + this.colorBlendingMode = blending; - this.alphaCompositionMode = PixelAlphaCompositionMode.SrcOver; - this.blendPercentage = opacity; - this.antialiasSubpixelDepth = 16; - this.antialias = enableAntialiasing; + this.alphaCompositionMode = PixelAlphaCompositionMode.SrcOver; + this.blendPercentage = opacity; + this.antialiasSubpixelDepth = 16; + this.antialias = enableAntialiasing; } - /// - /// Initializes a new instance of the struct. - /// + /// + /// 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) + /// alpha composition mode to apply to the drawing operation + public GraphicsOptions(bool enableAntialiasing, PixelColorBlendingMode blending, PixelAlphaCompositionMode composition, float opacity) { Guard.MustBeBetweenOrEqualTo(opacity, 0, 1, nameof(opacity)); - + this.colorBlendingMode = blending; - this.alphaCompositionMode = composition; - this.blendPercentage = opacity; - this.antialiasSubpixelDepth = 16; - this.antialias = enableAntialiasing; - } - - /// - /// Gets or sets a value indicating whether antialiasing should be applied. - /// - public bool Antialias - { - get => this.antialias ?? true; - set => this.antialias = value; - } - - /// - /// 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; - } - - /// - /// 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; - } - - // 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. - - /// - /// Gets or sets a value indicating the color blending mode to apply to the drawing operation - /// - public PixelColorBlendingMode ColorBlendingMode - { - get => this.colorBlendingMode; - set => this.colorBlendingMode = value; + this.alphaCompositionMode = composition; + this.blendPercentage = opacity; + this.antialiasSubpixelDepth = 16; + this.antialias = enableAntialiasing; } - /// - /// Gets or sets a value indicating the alpha composition mode to apply to the drawing operation - /// - public PixelAlphaCompositionMode AlphaCompositionMode - { - get => this.alphaCompositionMode; - set => this.alphaCompositionMode = value; + /// + /// Gets or sets a value indicating whether antialiasing should be applied. + /// + public bool Antialias + { + get => this.antialias ?? true; + set => this.antialias = value; + } + + /// + /// 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; + } + + /// + /// 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; + } + + // 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. + + /// + /// Gets or sets a value indicating the color blending mode to apply to the drawing operation + /// + public PixelColorBlendingMode ColorBlendingMode + { + get => this.colorBlendingMode; + set => this.colorBlendingMode = value; + } + + /// + /// Gets or sets a value indicating the alpha composition mode to apply to the drawing operation + /// + public PixelAlphaCompositionMode AlphaCompositionMode + { + get => this.alphaCompositionMode; + set => this.alphaCompositionMode = value; } /// @@ -149,8 +149,7 @@ namespace SixLabors.ImageSharp /// 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(TPixel color) - where TPixel : struct, IPixel + internal bool IsOpaqueColorWithoutBlending(Color color) { if (this.ColorBlendingMode != PixelColorBlendingMode.Normal) { @@ -174,6 +173,6 @@ namespace SixLabors.ImageSharp } return true; - } - } + } + } } \ No newline at end of file