// ReSharper disable VirtualMemberNeverOverriden.Global // ReSharper disable MemberCanBePrivate.Global // ReSharper disable VirtualMemberNeverOverridden.Global using System.Collections.Generic; using System.Linq; namespace RGB.NET.Core { /// /// /// /// Represents a basic brush. /// public abstract class AbstractBrush : AbstractDecoratable, IBrush { #region Properties & Fields /// public bool IsEnabled { get; set; } = true; /// public BrushCalculationMode BrushCalculationMode { get; set; } = BrushCalculationMode.Relative; /// public double Brightness { get; set; } /// public double Opacity { get; set; } /// public IList ColorCorrections { get; } = new List(); /// public Rectangle RenderedRectangle { get; protected set; } /// public Dictionary RenderedTargets { get; } = new Dictionary(); #endregion #region Constructors /// /// Initializes a new instance of the class. /// /// The overall percentage brightness of the brush. (default: 1.0) /// The overall percentage opacity of the brush. (default: 1.0) protected AbstractBrush(double brightness = 1, double opacity = 1) { this.Brightness = brightness; this.Opacity = opacity; } #endregion #region Methods /// public virtual void PerformRender(Rectangle rectangle, IEnumerable renderTargets) { RenderedRectangle = rectangle; RenderedTargets.Clear(); foreach (BrushRenderTarget renderTarget in renderTargets) { Color color = GetColorAtPoint(rectangle, renderTarget); color = ApplyDecorators(rectangle, renderTarget, color); RenderedTargets[renderTarget] = color; } } /// /// Applies all attached and enabled decorators to the brush. /// /// The rectangle in which the brush should be drawn. /// The target (key/point) from which the color should be taken. /// The to be modified. protected virtual Color ApplyDecorators(Rectangle rectangle, BrushRenderTarget renderTarget, Color color) { lock (Decorators) foreach (IBrushDecorator decorator in Decorators) if (decorator.IsEnabled) color = decorator.ManipulateColor(rectangle, renderTarget, color); return color; } /// public virtual void PerformFinalize() { List renderTargets = RenderedTargets.Keys.ToList(); foreach (BrushRenderTarget renderTarget in renderTargets) RenderedTargets[renderTarget] = FinalizeColor(RenderedTargets[renderTarget]); } /// /// Gets the color at an specific point assuming the brush is drawn into the given rectangle. /// /// The rectangle in which the brush should be drawn. /// The target (key/point) from which the color should be taken. /// The color at the specified point. protected abstract Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget); /// /// Finalizes the color by appliing the overall brightness and opacity.
/// This method should always be the last call of a implementation. ///
/// The color to finalize. /// The finalized color. protected virtual Color FinalizeColor(Color color) { if (ColorCorrections.Count > 0) foreach (IColorCorrection colorCorrection in ColorCorrections) color = colorCorrection.ApplyTo(color); // Since we use HSV to calculate there is no way to make a color 'brighter' than 100% // Be carefull with the naming: Since we use HSV the correct term is 'value' but outside we call it 'brightness' // THIS IS NOT A HSB CALCULATION!!! if (Brightness < 1) color = color.MultiplyHSV(value: Brightness.Clamp(0, 1)); if (Opacity < 1) color = color.MultiplyA(Opacity.Clamp(0, 1)); return color; } #endregion } }