1 use float::Float; 2 use num_traits::{One, Zero}; 3 4 use blend::{BlendFunction, PreAlpha}; 5 use {cast, clamp, ComponentWise}; 6 7 ///A trait for colors that can be blended together. 8 /// 9 ///Blending can either be performed through the predefined blend modes, or a 10 ///custom blend functions. 11 /// 12 ///_Note: The default implementations of the blend modes are meant for color 13 ///components in the range [0.0, 1.0] and may otherwise produce strange 14 ///results._ 15 pub trait Blend: Sized 16 where 17 <Self::Color as ComponentWise>::Scalar: Float, 18 { 19 ///The core color type. Typically `Self` for color types without alpha. 20 type Color: Blend<Color = Self::Color> + ComponentWise; 21 22 ///Convert the color to premultiplied alpha. into_premultiplied(self) -> PreAlpha<Self::Color, <Self::Color as ComponentWise>::Scalar>23 fn into_premultiplied(self) -> PreAlpha<Self::Color, <Self::Color as ComponentWise>::Scalar>; 24 25 ///Convert the color from premultiplied alpha. from_premultiplied( color: PreAlpha<Self::Color, <Self::Color as ComponentWise>::Scalar>, ) -> Self26 fn from_premultiplied( 27 color: PreAlpha<Self::Color, <Self::Color as ComponentWise>::Scalar>, 28 ) -> Self; 29 30 ///Blend self, as the source color, with `destination`, using 31 ///`blend_function`. Anything that implements `BlendFunction` is 32 ///acceptable, including functions and closures. 33 /// 34 ///``` 35 ///use palette::{LinSrgb, LinSrgba, Blend}; 36 ///use palette::blend::PreAlpha; 37 /// 38 ///type PreRgba = PreAlpha<LinSrgb<f32>, f32>; 39 /// 40 ///fn blend_mode(a: PreRgba, b: PreRgba) -> PreRgba { 41 /// PreAlpha { 42 /// color: LinSrgb::new(a.red * b.green, a.green * b.blue, a.blue * b.red), 43 /// alpha: a.alpha * b.alpha, 44 /// } 45 ///} 46 /// 47 ///let a = LinSrgba::new(0.2, 0.5, 0.1, 0.8); 48 ///let b = LinSrgba::new(0.6, 0.3, 0.5, 0.1); 49 ///let c = a.blend(b, blend_mode); 50 ///``` blend<F>(self, destination: Self, blend_function: F) -> Self where F: BlendFunction<Self::Color>,51 fn blend<F>(self, destination: Self, blend_function: F) -> Self 52 where 53 F: BlendFunction<Self::Color>, 54 { 55 Self::from_premultiplied( 56 blend_function.apply_to(self.into_premultiplied(), destination.into_premultiplied()), 57 ) 58 } 59 60 ///Place `self` over `other`. This is the good old common alpha 61 ///composition equation. over(self, other: Self) -> Self62 fn over(self, other: Self) -> Self { 63 let one = <Self::Color as ComponentWise>::Scalar::one(); 64 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 65 66 let src = self.into_premultiplied(); 67 let dst = other.into_premultiplied(); 68 69 let result = PreAlpha { 70 color: src 71 .color 72 .component_wise(&dst.color, |a, b| a + b * (one - src.alpha)), 73 alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one), 74 }; 75 76 Self::from_premultiplied(result) 77 } 78 79 ///Results in the parts of `self` that overlaps the visible parts of 80 ///`other`. inside(self, other: Self) -> Self81 fn inside(self, other: Self) -> Self { 82 let one = <Self::Color as ComponentWise>::Scalar::one(); 83 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 84 85 let src = self.into_premultiplied(); 86 let dst = other.into_premultiplied(); 87 88 let result = PreAlpha { 89 color: src.color.component_wise_self(|a| a * dst.alpha), 90 alpha: clamp(src.alpha * dst.alpha, zero, one), 91 }; 92 93 Self::from_premultiplied(result) 94 } 95 96 ///Results in the parts of `self` that lies outside the visible parts of 97 ///`other`. outside(self, other: Self) -> Self98 fn outside(self, other: Self) -> Self { 99 let one = <Self::Color as ComponentWise>::Scalar::one(); 100 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 101 102 let src = self.into_premultiplied(); 103 let dst = other.into_premultiplied(); 104 105 let result = PreAlpha { 106 color: src.color.component_wise_self(|a| a * (one - dst.alpha)), 107 alpha: clamp(src.alpha * (one - dst.alpha), zero, one), 108 }; 109 110 Self::from_premultiplied(result) 111 } 112 113 ///Place `self` over only the visible parts of `other`. atop(self, other: Self) -> Self114 fn atop(self, other: Self) -> Self { 115 let one = <Self::Color as ComponentWise>::Scalar::one(); 116 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 117 118 let src = self.into_premultiplied(); 119 let dst = other.into_premultiplied(); 120 121 let result = PreAlpha { 122 color: src 123 .color 124 .component_wise(&dst.color, |a, b| a * dst.alpha + b * (one - src.alpha)), 125 alpha: clamp(dst.alpha, zero, one), 126 }; 127 128 Self::from_premultiplied(result) 129 } 130 131 ///Results in either `self` or `other`, where they do not overlap. xor(self, other: Self) -> Self132 fn xor(self, other: Self) -> Self { 133 let one = <Self::Color as ComponentWise>::Scalar::one(); 134 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 135 let two = one + one; 136 137 let src = self.into_premultiplied(); 138 let dst = other.into_premultiplied(); 139 140 let result = PreAlpha { 141 color: src.color.component_wise(&dst.color, |a, b| { 142 a * (one - dst.alpha) + b * (one - src.alpha) 143 }), 144 alpha: clamp( 145 src.alpha + dst.alpha - two * src.alpha * dst.alpha, 146 zero, 147 one, 148 ), 149 }; 150 151 Self::from_premultiplied(result) 152 } 153 154 ///Add `self` and `other`. This uses the alpha component to regulate the 155 ///effect, so it's not just plain component wise addition. plus(self, other: Self) -> Self156 fn plus(self, other: Self) -> Self { 157 let one = <Self::Color as ComponentWise>::Scalar::one(); 158 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 159 160 let src = self.into_premultiplied(); 161 let dst = other.into_premultiplied(); 162 163 let result = PreAlpha { 164 color: src.color.component_wise(&dst.color, |a, b| a + b), 165 alpha: clamp(src.alpha + dst.alpha, zero, one), 166 }; 167 168 Self::from_premultiplied(result) 169 } 170 171 ///Multiply `self` with `other`. This uses the alpha component to regulate 172 ///the effect, so it's not just plain component wise multiplication. multiply(self, other: Self) -> Self173 fn multiply(self, other: Self) -> Self { 174 let one = <Self::Color as ComponentWise>::Scalar::one(); 175 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 176 177 let src = self.into_premultiplied(); 178 let dst = other.into_premultiplied(); 179 180 let result = PreAlpha { 181 color: src.color.component_wise(&dst.color, |a, b| { 182 a * b + a * (one - dst.alpha) + b * (one - src.alpha) 183 }), 184 alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one), 185 }; 186 187 Self::from_premultiplied(result) 188 } 189 190 ///Make a color which is at least as light as `self` or `other`. screen(self, other: Self) -> Self191 fn screen(self, other: Self) -> Self { 192 let one = <Self::Color as ComponentWise>::Scalar::one(); 193 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 194 195 let src = self.into_premultiplied(); 196 let dst = other.into_premultiplied(); 197 198 let result = PreAlpha { 199 color: src.color.component_wise(&dst.color, |a, b| a + b - a * b), 200 alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one), 201 }; 202 203 Self::from_premultiplied(result) 204 } 205 206 ///Multiply `self` or `other` if other is dark, or screen them if `other` 207 ///is light. This results in an S curve. overlay(self, other: Self) -> Self208 fn overlay(self, other: Self) -> Self { 209 let one = <Self::Color as ComponentWise>::Scalar::one(); 210 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 211 let two = one + one; 212 213 let src = self.into_premultiplied(); 214 let dst = other.into_premultiplied(); 215 216 let result = PreAlpha { 217 color: src.color.component_wise(&dst.color, |a, b| { 218 if b * two <= dst.alpha { 219 two * a * b + a * (one - dst.alpha) + b * (one - src.alpha) 220 } else { 221 a * (one + dst.alpha) + b * (one + src.alpha) 222 - two * a * b 223 - src.alpha * dst.alpha 224 } 225 }), 226 alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one), 227 }; 228 229 Self::from_premultiplied(result) 230 } 231 232 ///Return the darkest parts of `self` and `other`. darken(self, other: Self) -> Self233 fn darken(self, other: Self) -> Self { 234 let one = <Self::Color as ComponentWise>::Scalar::one(); 235 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 236 237 let src = self.into_premultiplied(); 238 let dst = other.into_premultiplied(); 239 240 let result = PreAlpha { 241 color: src.color.component_wise(&dst.color, |a, b| { 242 (a * dst.alpha).min(b * src.alpha) + a * (one - dst.alpha) + b * (one - src.alpha) 243 }), 244 alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one), 245 }; 246 247 Self::from_premultiplied(result) 248 } 249 250 ///Return the lightest parts of `self` and `other`. lighten(self, other: Self) -> Self251 fn lighten(self, other: Self) -> Self { 252 let one = <Self::Color as ComponentWise>::Scalar::one(); 253 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 254 255 let src = self.into_premultiplied(); 256 let dst = other.into_premultiplied(); 257 258 let result = PreAlpha { 259 color: src.color.component_wise(&dst.color, |a, b| { 260 (a * dst.alpha).max(b * src.alpha) + a * (one - dst.alpha) + b * (one - src.alpha) 261 }), 262 alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one), 263 }; 264 265 Self::from_premultiplied(result) 266 } 267 268 ///Lighten `other` to reflect `self`. Results in `other` if `self` is 269 ///black. dodge(self, other: Self) -> Self270 fn dodge(self, other: Self) -> Self { 271 let one = <Self::Color as ComponentWise>::Scalar::one(); 272 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 273 274 let src = self.into_premultiplied(); 275 let dst = other.into_premultiplied(); 276 277 let result = PreAlpha { 278 color: src.color.component_wise(&dst.color, |a, b| { 279 if a == src.alpha && !b.is_normal() { 280 a * (one - dst.alpha) 281 } else if a == src.alpha { 282 src.alpha * dst.alpha + a * (one - dst.alpha) + b * (one - src.alpha) 283 } else { 284 src.alpha * dst.alpha * one.min((b / dst.alpha) * src.alpha / (src.alpha - a)) 285 + a * (one - dst.alpha) 286 + b * (one - src.alpha) 287 } 288 }), 289 alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one), 290 }; 291 292 Self::from_premultiplied(result) 293 } 294 295 ///Darken `other` to reflect `self`. Results in `other` if `self` is 296 ///white. burn(self, other: Self) -> Self297 fn burn(self, other: Self) -> Self { 298 let one = <Self::Color as ComponentWise>::Scalar::one(); 299 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 300 301 let src = self.into_premultiplied(); 302 let dst = other.into_premultiplied(); 303 304 let result = PreAlpha { 305 color: src.color.component_wise(&dst.color, |a, b| { 306 if !a.is_normal() && b == dst.alpha { 307 src.alpha * dst.alpha + b * (one - src.alpha) 308 } else if !a.is_normal() { 309 b * (one - src.alpha) 310 } else { 311 src.alpha * dst.alpha * (one - one.min((one - b / dst.alpha) * src.alpha / a)) 312 + a * (one - dst.alpha) 313 + b * (one - src.alpha) 314 } 315 }), 316 alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one), 317 }; 318 319 Self::from_premultiplied(result) 320 } 321 322 ///Multiply `self` or `other` if other is dark, or screen them if `self` 323 ///is light. This is similar to `overlay`, but depends on `self` instead 324 ///of `other`. hard_light(self, other: Self) -> Self325 fn hard_light(self, other: Self) -> Self { 326 let one = <Self::Color as ComponentWise>::Scalar::one(); 327 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 328 let two = one + one; 329 330 let src = self.into_premultiplied(); 331 let dst = other.into_premultiplied(); 332 333 let result = PreAlpha { 334 color: src.color.component_wise(&dst.color, |a, b| { 335 if a * two <= src.alpha { 336 two * a * b + a * (one - dst.alpha) + b * (one - src.alpha) 337 } else { 338 a * (one + dst.alpha) + b * (one + src.alpha) 339 - two * a * b 340 - src.alpha * dst.alpha 341 } 342 }), 343 alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one), 344 }; 345 346 Self::from_premultiplied(result) 347 } 348 349 ///Lighten `other` if `self` is light, or darken `other` as if it's burned 350 ///if `self` is dark. The effect is increased if the components of `self` 351 ///is further from 0.5. soft_light(self, other: Self) -> Self352 fn soft_light(self, other: Self) -> Self { 353 let one = <Self::Color as ComponentWise>::Scalar::one(); 354 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 355 let two = one + one; 356 357 let src = self.into_premultiplied(); 358 let dst = other.into_premultiplied(); 359 360 let result = PreAlpha { 361 color: src.color.component_wise(&dst.color, |a, b| { 362 let m = if dst.alpha.is_normal() { 363 b / dst.alpha 364 } else { 365 zero 366 }; 367 368 if a * two <= src.alpha { 369 b * (src.alpha + (two * a - src.alpha) * (one - m)) 370 + a * (one - dst.alpha) 371 + b * (one - src.alpha) 372 } else if b * cast(4.0) <= dst.alpha { 373 let m2 = m * m; 374 let m3 = m2 * m; 375 376 dst.alpha 377 * (two * a - src.alpha) 378 * (m3 * cast(16.0) - m2 * cast(12.0) - m * cast(3.0)) 379 + a 380 - a * dst.alpha 381 + b 382 } else { 383 dst.alpha * (two * a - src.alpha) * (m.sqrt() - m) + a - a * dst.alpha + b 384 } 385 }), 386 alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one), 387 }; 388 389 Self::from_premultiplied(result) 390 } 391 392 ///Return the absolute difference between `self` and `other`. It's 393 ///basically `abs(self - other)`, but regulated by the alpha component. difference(self, other: Self) -> Self394 fn difference(self, other: Self) -> Self { 395 let one = <Self::Color as ComponentWise>::Scalar::one(); 396 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 397 let two = one + one; 398 399 let src = self.into_premultiplied(); 400 let dst = other.into_premultiplied(); 401 402 let result = PreAlpha { 403 color: src.color.component_wise(&dst.color, |a, b| { 404 a + b - two * (a * dst.alpha).min(b * src.alpha) 405 }), 406 alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one), 407 }; 408 409 Self::from_premultiplied(result) 410 } 411 412 ///Similar to `difference`, but appears to result in a lower contrast. 413 ///`other` is inverted if `self` is white, and preserved if `self` is 414 ///black. exclusion(self, other: Self) -> Self415 fn exclusion(self, other: Self) -> Self { 416 let one = <Self::Color as ComponentWise>::Scalar::one(); 417 let zero = <Self::Color as ComponentWise>::Scalar::zero(); 418 let two = one + one; 419 420 let src = self.into_premultiplied(); 421 let dst = other.into_premultiplied(); 422 423 let result = PreAlpha { 424 color: src 425 .color 426 .component_wise(&dst.color, |a, b| a + b - two * a * b), 427 alpha: clamp(src.alpha + dst.alpha - src.alpha * dst.alpha, zero, one), 428 }; 429 430 Self::from_premultiplied(result) 431 } 432 } 433