// 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 RenderMode CalculationMode { get; set; } = RenderMode.Relative; /// public float Brightness { get; set; } /// public float Opacity { get; set; } #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(float brightness = 1, float opacity = 1) { this.Brightness = brightness; this.Opacity = opacity; } #endregion #region Methods public IEnumerable<(RenderTarget renderTarget, Color color)> Render(Rectangle rectangle, IEnumerable renderTargets) { foreach (RenderTarget renderTarget in renderTargets) { Color color = GetColorAtPoint(rectangle, renderTarget); ApplyDecorators(rectangle, renderTarget, ref color); FinalizeColor(ref color); yield return (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 void ApplyDecorators(in Rectangle rectangle, in RenderTarget renderTarget, ref Color color) { lock (Decorators) foreach (IBrushDecorator decorator in Decorators) if (decorator.IsEnabled) decorator.ManipulateColor(rectangle, renderTarget, ref color); } /// /// 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(in Rectangle rectangle, in RenderTarget renderTarget); /// /// Finalizes the color by appliing the overall brightness and opacity.
///
/// The color to finalize. /// The finalized color. protected virtual void FinalizeColor(ref Color 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)); } #endregion } }