ass_renderer/pipeline/compositing/
mod.rs1#[cfg(feature = "nostd")]
4use alloc::{vec, vec::Vec};
5#[cfg(not(feature = "nostd"))]
6use std::vec::Vec;
7
8use crate::pipeline::IntermediateLayer;
9use crate::utils::RenderError;
10
11#[derive(Debug, Clone, Copy)]
13pub enum CompositeMode {
14 Normal,
16 Add,
18 Multiply,
20 Xor,
22}
23
24pub fn composite_layers(
26 layers: &[IntermediateLayer],
27 width: u32,
28 height: u32,
29) -> Result<Vec<u8>, RenderError> {
30 let mut output = vec![0u8; (width * height * 4) as usize];
31
32 for layer in layers {
33 composite_layer(layer, &mut output, width, height)?;
34 }
35
36 Ok(output)
37}
38
39fn composite_layer(
41 layer: &IntermediateLayer,
42 output: &mut [u8],
43 width: u32,
44 height: u32,
45) -> Result<(), RenderError> {
46 let _ = (layer, output, width, height);
48 Ok(())
49}
50
51pub fn alpha_blend(src: [u8; 4], dst: [u8; 4]) -> [u8; 4] {
58 let src_alpha = src[3] as u32;
60
61 if src_alpha == 0 {
62 return dst;
64 }
65
66 if src_alpha == 255 && dst[3] == 0 {
67 return src;
69 }
70
71 let inv_src_alpha = 255 - src_alpha;
74
75 let out_r = ((src[0] as u32 * src_alpha + dst[0] as u32 * inv_src_alpha + 255) >> 8) as u8;
77 let out_g = ((src[1] as u32 * src_alpha + dst[1] as u32 * inv_src_alpha + 255) >> 8) as u8;
78 let out_b = ((src[2] as u32 * src_alpha + dst[2] as u32 * inv_src_alpha + 255) >> 8) as u8;
79
80 let dst_alpha = dst[3] as u32;
82 let out_alpha = ((src_alpha * 255 + dst_alpha * inv_src_alpha + 255) >> 8) as u8;
83
84 [out_r, out_g, out_b, out_alpha]
85}