use crate::media::{Color, ColorMatrix, ColorMatrixAlphaMode, Colors};
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct CompositionEffectSourceParameter {
name: String,
}
impl CompositionEffectSourceParameter {
pub fn new(name: impl Into<String>) -> Self {
Self { name: name.into() }
}
pub fn name(&self) -> &str {
&self.name
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[repr(i32)]
pub enum EffectBorderMode {
#[default]
Soft = 0,
Hard = 1,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[repr(i32)]
pub enum EffectOptimization {
Speed = 0,
#[default]
Balanced = 1,
Quality = 2,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[repr(i32)]
pub enum CanvasComposite {
#[default]
SourceOver = 0,
DestinationOver = 1,
SourceIn = 2,
DestinationIn = 3,
SourceOut = 4,
DestinationOut = 5,
SourceAtop = 6,
DestinationAtop = 7,
Xor = 8,
Add = 9,
Copy = 10,
BoundedCopy = 11,
MaskInvert = 12,
}
#[derive(Clone, Debug, PartialEq)]
pub enum GraphicsEffectSource {
Parameter(CompositionEffectSourceParameter),
Effect(Box<GraphicsEffect>),
}
impl From<CompositionEffectSourceParameter> for GraphicsEffectSource {
fn from(parameter: CompositionEffectSourceParameter) -> Self {
GraphicsEffectSource::Parameter(parameter)
}
}
impl From<GraphicsEffect> for GraphicsEffectSource {
fn from(effect: GraphicsEffect) -> Self {
GraphicsEffectSource::Effect(Box::new(effect))
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum GraphicsEffect {
GaussianBlur(GaussianBlurEffect),
Opacity(OpacityEffect),
CrossFade(CrossFadeEffect),
Composite(CompositeEffect),
ColorSource(ColorSourceEffect),
Saturation(SaturationEffect),
Blend(BlendEffect),
ColorMatrix(ColorMatrixEffect),
Tint(TintEffect),
Invert(InvertEffect),
Grayscale(GrayscaleEffect),
LuminanceToAlpha(LuminanceToAlphaEffect),
ArithmeticComposite(ArithmeticCompositeEffect),
AlphaMask(AlphaMaskEffect),
Border(BorderEffect),
SceneLighting(SceneLightingEffect),
Shadow(ShadowEffect),
}
impl GraphicsEffect {
pub fn name(&self) -> &str {
match self {
GraphicsEffect::GaussianBlur(effect) => &effect.name,
GraphicsEffect::Opacity(effect) => &effect.name,
GraphicsEffect::CrossFade(effect) => &effect.name,
GraphicsEffect::Composite(effect) => &effect.name,
GraphicsEffect::ColorSource(effect) => &effect.name,
GraphicsEffect::Saturation(effect) => &effect.name,
GraphicsEffect::Blend(effect) => &effect.name,
GraphicsEffect::ColorMatrix(effect) => &effect.name,
GraphicsEffect::Tint(effect) => &effect.name,
GraphicsEffect::Invert(effect) => &effect.name,
GraphicsEffect::Grayscale(effect) => &effect.name,
GraphicsEffect::LuminanceToAlpha(effect) => &effect.name,
GraphicsEffect::ArithmeticComposite(effect) => &effect.name,
GraphicsEffect::AlphaMask(effect) => &effect.name,
GraphicsEffect::Border(effect) => &effect.name,
GraphicsEffect::SceneLighting(effect) => &effect.name,
GraphicsEffect::Shadow(effect) => &effect.name,
}
}
pub fn type_name(&self) -> &'static str {
match self {
GraphicsEffect::GaussianBlur(_) => "GaussianBlurEffect",
GraphicsEffect::Opacity(_) => "OpacityEffect",
GraphicsEffect::CrossFade(_) => "CrossFadeEffect",
GraphicsEffect::Composite(_) => "CompositeEffect",
GraphicsEffect::ColorSource(_) => "ColorSourceEffect",
GraphicsEffect::Saturation(_) => "SaturationEffect",
GraphicsEffect::Blend(_) => "BlendEffect",
GraphicsEffect::ColorMatrix(_) => "ColorMatrixEffect",
GraphicsEffect::Tint(_) => "TintEffect",
GraphicsEffect::Invert(_) => "InvertEffect",
GraphicsEffect::Grayscale(_) => "GrayscaleEffect",
GraphicsEffect::LuminanceToAlpha(_) => "LuminanceToAlphaEffect",
GraphicsEffect::ArithmeticComposite(_) => "ArithmeticCompositeEffect",
GraphicsEffect::AlphaMask(_) => "AlphaMaskEffect",
GraphicsEffect::Border(_) => "BorderEffect",
GraphicsEffect::SceneLighting(_) => "SceneLightingEffect",
GraphicsEffect::Shadow(_) => "ShadowEffect",
}
}
}
macro_rules! graphics_effect_conversions {
($($ty:ident => $variant:ident),* $(,)?) => {$(
impl From<$ty> for GraphicsEffect {
fn from(effect: $ty) -> Self {
GraphicsEffect::$variant(effect)
}
}
impl From<$ty> for GraphicsEffectSource {
fn from(effect: $ty) -> Self {
GraphicsEffectSource::Effect(Box::new(GraphicsEffect::$variant(effect)))
}
}
)*};
}
graphics_effect_conversions! {
GaussianBlurEffect => GaussianBlur,
OpacityEffect => Opacity,
CrossFadeEffect => CrossFade,
CompositeEffect => Composite,
ColorSourceEffect => ColorSource,
SaturationEffect => Saturation,
BlendEffect => Blend,
ColorMatrixEffect => ColorMatrix,
TintEffect => Tint,
InvertEffect => Invert,
GrayscaleEffect => Grayscale,
LuminanceToAlphaEffect => LuminanceToAlpha,
ArithmeticCompositeEffect => ArithmeticComposite,
AlphaMaskEffect => AlphaMask,
BorderEffect => Border,
ShadowEffect => Shadow,
SceneLightingEffect => SceneLighting,
}
#[derive(Clone, Debug, PartialEq)]
pub struct GaussianBlurEffect {
pub name: String,
pub blur_amount: f32,
pub border_mode: EffectBorderMode,
pub optimization: EffectOptimization,
pub source: Option<GraphicsEffectSource>,
}
impl Default for GaussianBlurEffect {
fn default() -> Self {
Self {
name: String::new(),
blur_amount: 3.0,
border_mode: EffectBorderMode::Soft,
optimization: EffectOptimization::Balanced,
source: None,
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct OpacityEffect {
pub name: String,
pub opacity: f32,
pub source: Option<GraphicsEffectSource>,
}
impl Default for OpacityEffect {
fn default() -> Self {
Self { name: String::new(), opacity: 1.0, source: None }
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct CrossFadeEffect {
pub name: String,
pub weight: f32,
pub source1: Option<GraphicsEffectSource>,
pub source2: Option<GraphicsEffectSource>,
}
impl Default for CrossFadeEffect {
fn default() -> Self {
Self { name: String::new(), weight: 0.5, source1: None, source2: None }
}
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct CompositeEffect {
pub name: String,
pub mode: CanvasComposite,
pub sources: Vec<GraphicsEffectSource>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct ColorSourceEffect {
pub name: String,
pub color: Color,
}
impl Default for ColorSourceEffect {
fn default() -> Self {
Self { name: String::new(), color: Colors::BLACK }
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct SaturationEffect {
pub name: String,
pub saturation: f32,
pub source: Option<GraphicsEffectSource>,
}
impl Default for SaturationEffect {
fn default() -> Self {
Self { name: String::new(), saturation: 0.5, source: None }
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[repr(i32)]
pub enum BlendEffectMode {
#[default]
Multiply = 0,
Screen = 1,
Darken = 2,
Lighten = 3,
Dissolve = 4,
ColorBurn = 5,
LinearBurn = 6,
DarkerColor = 7,
LighterColor = 8,
ColorDodge = 9,
LinearDodge = 10,
Overlay = 11,
SoftLight = 12,
HardLight = 13,
VividLight = 14,
LinearLight = 15,
PinLight = 16,
HardMix = 17,
Difference = 18,
Exclusion = 19,
Hue = 20,
Saturation = 21,
Color = 22,
Luminosity = 23,
Subtract = 24,
Division = 25,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct BlendEffect {
pub name: String,
pub mode: BlendEffectMode,
pub background: Option<GraphicsEffectSource>,
pub foreground: Option<GraphicsEffectSource>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct ColorMatrixEffect {
pub name: String,
pub color_matrix: ColorMatrix,
pub alpha_mode: ColorMatrixAlphaMode,
pub clamp_output: bool,
pub source: Option<GraphicsEffectSource>,
}
impl Default for ColorMatrixEffect {
fn default() -> Self {
Self {
name: String::new(),
color_matrix: ColorMatrix::IDENTITY,
alpha_mode: ColorMatrixAlphaMode::Premultiplied,
clamp_output: false,
source: None,
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct TintEffect {
pub name: String,
pub color: Color,
pub clamp_output: bool,
pub source: Option<GraphicsEffectSource>,
}
impl Default for TintEffect {
fn default() -> Self {
Self { name: String::new(), color: Colors::WHITE, clamp_output: false, source: None }
}
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct InvertEffect {
pub name: String,
pub source: Option<GraphicsEffectSource>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct GrayscaleEffect {
pub name: String,
pub source: Option<GraphicsEffectSource>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct LuminanceToAlphaEffect {
pub name: String,
pub source: Option<GraphicsEffectSource>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct ArithmeticCompositeEffect {
pub name: String,
pub multiply_amount: f32,
pub source1_amount: f32,
pub source2_amount: f32,
pub offset: f32,
pub clamp_output: bool,
pub source1: Option<GraphicsEffectSource>,
pub source2: Option<GraphicsEffectSource>,
}
impl Default for ArithmeticCompositeEffect {
fn default() -> Self {
Self {
name: String::new(),
multiply_amount: 1.0,
source1_amount: 0.0,
source2_amount: 0.0,
offset: 0.0,
clamp_output: false,
source1: None,
source2: None,
}
}
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct AlphaMaskEffect {
pub name: String,
pub source: Option<GraphicsEffectSource>,
pub alpha_mask: Option<GraphicsEffectSource>,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[repr(i32)]
pub enum CanvasEdgeBehavior {
#[default]
Clamp = 0,
Wrap = 1,
Mirror = 2,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct BorderEffect {
pub name: String,
pub extend_x: CanvasEdgeBehavior,
pub extend_y: CanvasEdgeBehavior,
pub source: Option<GraphicsEffectSource>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct SceneLightingEffect {
pub name: String,
pub ambient_amount: f32,
pub diffuse_amount: f32,
pub specular_amount: f32,
pub specular_shine: f32,
pub normal_map_source: Option<GraphicsEffectSource>,
}
impl Default for SceneLightingEffect {
fn default() -> Self {
Self {
name: String::new(),
ambient_amount: 1.0,
diffuse_amount: 1.0,
specular_amount: 0.0,
specular_shine: 16.0,
normal_map_source: None,
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct ShadowEffect {
pub name: String,
pub blur_amount: f32,
pub shadow_color: Color,
pub optimization: EffectOptimization,
pub source: Option<GraphicsEffectSource>,
}
impl Default for ShadowEffect {
fn default() -> Self {
Self {
name: String::new(),
blur_amount: 1.0,
shadow_color: Color::from_argb(255, 0, 0, 0),
optimization: EffectOptimization::Balanced,
source: None,
}
}
}