use super::*;
impl GfxCtx<'_> {
pub fn push_layer(&mut self, width: f64, height: f64) {
self.push_layer_with_alpha(width, height, 1.0);
}
pub fn push_layer_with_alpha(&mut self, width: f64, height: f64, alpha: f64) {
let origin_x = self.state.transform.tx;
let origin_y = self.state.transform.ty;
let (scale_x, scale_y) = self.state.transform.scaling_abs();
let scale_x = scale_x.max(1e-6);
let scale_y = scale_y.max(1e-6);
let phys_w = (width * scale_x).ceil().max(1.0) as u32;
let phys_h = (height * scale_y).ceil().max(1.0) as u32;
let saved_state = self.state.clone();
let saved_stack = std::mem::take(&mut self.state_stack);
let layer_fb = Framebuffer::new(phys_w, phys_h);
self.layer_stack.push(LayerEntry {
fb: layer_fb,
saved_state,
saved_stack,
origin_x,
origin_y,
alpha: alpha.clamp(0.0, 1.0),
});
self.state.transform = TransAffine::new_scaling(scale_x, scale_y);
self.state.clip = None;
}
pub fn pop_layer(&mut self) {
let Some(layer) = self.layer_stack.pop() else {
return;
};
let ox = layer.origin_x as i32;
let oy = layer.origin_y as i32;
self.state = layer.saved_state;
self.state_stack = layer.saved_stack;
let parent_clip = self.state.clip;
if let Some(top) = self.layer_stack.last_mut() {
composite_framebuffers(&mut top.fb, &layer.fb, ox, oy, layer.alpha, parent_clip);
} else {
composite_framebuffers(self.base_fb, &layer.fb, ox, oy, layer.alpha, parent_clip);
}
}
}