using System; using SixLabors.ImageSharp.PixelFormats; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Drawing.Brushes.GradientBrushes { /// /// A Circular Gradient Brush, defined by center point and radius. /// /// The pixel format. public class RadialGradientBrush : AbstractGradientBrush where TPixel : struct, IPixel { private readonly Point center; private readonly float radius; /// /// The center of the circular gradient and 0 for the color stops. /// The radius of the circular gradient and 1 for the color stops. /// the color stops as defined in base class. public RadialGradientBrush( Point center, float radius, params ColorStop[] colorStops) : base(colorStops) { this.center = center; this.radius = radius; } /// public override BrushApplicator CreateApplicator( ImageFrame source, RectangleF region, GraphicsOptions options) => new RadialGradientBrushApplicator( source, options, this.center, this.radius, this.ColorStops, region); /// protected class RadialGradientBrushApplicator : AbstractGradientBrushApplicator { private readonly Point center; private readonly float radius; /// /// Initializes a new instance of the class. /// /// The target image /// The options. /// Center point of the gradient. /// Radius of the gradient. /// Definition of colors. /// TODO ! public RadialGradientBrushApplicator( ImageFrame target, GraphicsOptions options, Point center, float radius, ColorStop[] colorStops, RectangleF region) : base(target, options, colorStops, region) { 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. /// /// The X coordinate of the target pixel. /// The Y coordinate of the target pixel. /// the position on the color gradient. protected override float PositionOnGradient(int x, int y) { float distance = (float)Math.Sqrt(Math.Pow(this.center.X - x, 2) + Math.Pow(this.center.Y - y, 2)); return distance / this.radius; } internal override void Apply(Span scanline, int x, int y) { // TODO: each row is symmetric across center, so we can calculate half of it and mirror it to improve performance. base.Apply(scanline, x, y); } } } }