// 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));
}
}
}
}
}