1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//! That module exports blending-related types and functions.
//!
//! Given two pixels *src* and *dst* – source and destination, we associate each pixel a blending
//! factor – respectively, *srcK* and *dstK*. *src* is the pixel being computed, and *dst* is the
//! pixel that is already stored in the framebuffer.
//!
//! The pixels can be blended in several ways. See the documentation of [`Equation`] for further
//! details.
//!
//! The factors are encoded with [`Factor`].
//!
//! [`Equation`]: crate::blending::Equation
//! [`Factor`]: crate::blending::Factor

/// Blending equation. Used to state how blending factors and pixel data should be blended.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Equation {
  /// `Additive` represents the following blending equation:
  ///
  /// > `blended = src * srcK + dst * dstK`
  Additive,
  /// `Subtract` represents the following blending equation:
  ///
  /// > `blended = src * srcK - dst * dstK`
  Subtract,
  /// Because subtracting is not commutative, `ReverseSubtract` represents the following additional
  /// blending equation:
  ///
  /// > `blended = dst * dstK - src * srcK`
  ReverseSubtract,
  /// `Min` represents the following blending equation:
  ///
  /// > `blended = min(src, dst)`
  Min,
  /// `Max` represents the following blending equation:
  ///
  /// > `blended = max(src, dst)`
  Max,
}

/// Blending factors. Pixel data are multiplied by these factors to achieve several effects driven
/// by *blending equations*.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Factor {
  /// `1 * color = color`
  One,
  /// `0 * color = 0`
  Zero,
  /// `src * color`
  SrcColor,
  /// `(1 - src) * color`
  SrcColorComplement,
  /// `dst * color`
  DestColor,
  /// `(1 - dst) * color`
  DestColorComplement,
  /// `srcA * color`
  SrcAlpha,
  /// `(1 - src) * color`
  SrcAlphaComplement,
  /// `dstA * color`
  DstAlpha,
  /// `(1 - dstA) * color`
  DstAlphaComplement,
  /// For colors, `min(srcA, 1 - dstA)`, for alpha, `1`
  SrcAlphaSaturate,
}

/// Basic blending configuration.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Blending {
  /// Blending equation to use.
  pub equation: Equation,
  /// Source factor.
  pub src: Factor,
  /// Destination factor.
  pub dst: Factor,
}

/// Blending configuration to represent combined or separate options.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum BlendingMode {
  /// Blending with combined RGBA.
  Combined(Blending),

  /// Blending with RGB and alpha separately.
  Separate {
    /// Blending configuration for RGB components.
    rgb: Blending,
    /// Blending configuration for alpha component.
    alpha: Blending,
  },
}

impl From<Blending> for BlendingMode {
  fn from(blending: Blending) -> Self {
    BlendingMode::Combined(blending)
  }
}