🎉 Implement drawing with blend mode (single fill)

This commit is contained in:
Belén Albeza 2024-11-13 16:39:26 +01:00
parent 7458165e51
commit 966e942a7f
5 changed files with 87 additions and 15 deletions

View file

@ -128,6 +128,14 @@ pub extern "C" fn clear_shape_fills() {
}
}
#[no_mangle]
pub extern "C" fn set_shape_blend_mode(mode: i32) {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
shape.set_blend_mode(shapes::BlendMode::from(mode));
}
}
fn main() {
render::init_gl();
}

View file

@ -141,7 +141,10 @@ fn render_single_shape(surface: &mut skia::Surface, shape: &Shape) {
surface.canvas().concat(&matrix);
// TODO: use blend mode for the shape as a whole, not in each fill
for fill in shape.fills().rev() {
surface.canvas().draw_rect(r, &fill.to_paint());
let mut p = fill.to_paint();
p.set_blend_mode(shape.blend_mode.into());
surface.canvas().draw_rect(r, &p);
}
}

View file

@ -72,7 +72,6 @@ impl Fill {
p.set_color(*color);
p.set_style(skia::PaintStyle::Fill);
p.set_anti_alias(true);
// TODO: get proper blend mode. See https://tree.taiga.io/project/penpot/task/9275
p.set_blend_mode(skia::BlendMode::SrcOver);
p
}
@ -80,15 +79,43 @@ impl Fill {
}
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct BlendMode(skia::BlendMode);
impl Default for BlendMode {
fn default() -> Self {
BlendMode(skia::BlendMode::SrcOver)
}
}
impl From<i32> for BlendMode {
fn from(value: i32) -> Self {
if value <= skia::BlendMode::Luminosity as i32 {
unsafe { Self(std::mem::transmute(value)) }
} else {
Self::default()
}
}
}
impl Into<skia::BlendMode> for BlendMode {
fn into(self) -> skia::BlendMode {
match self {
Self(skia_blend) => skia_blend,
}
}
}
#[derive(Debug, Clone)]
pub struct Shape {
pub id: Uuid,
pub children: Vec::<Uuid>,
pub children: Vec<Uuid>,
pub kind: Kind,
pub selrect: Rect,
pub transform: Matrix,
pub rotation: f32,
fills: Vec<Fill>,
pub blend_mode: BlendMode,
}
impl Shape {
@ -101,6 +128,7 @@ impl Shape {
transform: Matrix::identity(),
rotation: 0.,
fills: vec![],
blend_mode: BlendMode::default(),
}
}
@ -127,4 +155,8 @@ impl Shape {
pub fn clear_fills(&mut self) {
self.fills.clear();
}
pub fn set_blend_mode(&mut self, mode: BlendMode) {
self.blend_mode = mode;
}
}