// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using SixLabors.ImageSharp.PixelFormats; using System; namespace SixLabors.ImageSharp.Drawing.Processing { /// /// Provides an implementation of a solid brush for painting solid color areas. /// public sealed class SolidBrush : Brush { /// /// Initializes a new instance of the class. /// /// The color. public SolidBrush(Color color) => this.Color = color; /// /// Gets the color. /// public Color Color { get; } /// public override BrushRenderer CreateRenderer( Configuration configuration, GraphicsOptions options, int canvasWidth, RectangleF region) => new SolidBrushRenderer(configuration, options, canvasWidth, this.Color.ToPixel()); /// public override bool Equals(Brush? other) { if (other is SolidBrush sb) { return sb.Color.Equals(this.Color); } return false; } /// public override int GetHashCode() => this.Color.GetHashCode(); /// /// The solid brush applicator. /// /// The pixel format. private sealed class SolidBrushRenderer : BrushRenderer where TPixel : unmanaged, IPixel { private readonly TPixel color; /// /// Initializes a new instance of the class. /// /// The configuration instance to use when performing operations. /// The graphics options. /// The canvas width for the current render pass. /// The color. public SolidBrushRenderer( Configuration configuration, GraphicsOptions options, int canvasWidth, TPixel color) : base(configuration, options, canvasWidth) => this.color = color; /// public override void Apply( Span destinationRow, ReadOnlySpan scanline, int x, int y, BrushWorkspace workspace) { // Constrain the spans to each other if (destinationRow.Length > scanline.Length) { destinationRow = destinationRow[..scanline.Length]; } else { scanline = scanline[..destinationRow.Length]; } Configuration configuration = this.Configuration; if (this.Options.BlendPercentage == 1F) { this.Blender.Blend( configuration, destinationRow, destinationRow, this.color, scanline, workspace.GetBlendScratch(scanline.Length, 2)); } else { Span amounts = workspace.GetAmounts(scanline.Length); for (int i = 0; i < scanline.Length; i++) { amounts[i] = scanline[i] * this.Options.BlendPercentage; } this.Blender.Blend( configuration, destinationRow, destinationRow, this.color, amounts, workspace.GetBlendScratch(scanline.Length, 2)); } } } } }