🎉 Render wasm blur support

This commit is contained in:
Alejandro Alonso 2025-01-09 13:51:12 +01:00
parent d500058aa9
commit 7cc33b1a1a
8 changed files with 117 additions and 11 deletions

View file

@ -347,6 +347,14 @@ pub extern "C" fn set_shape_hidden(hidden: bool) {
}
}
#[no_mangle]
pub extern "C" fn set_shape_blur(blur_type: u8, hidden: bool, value: f32) {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
if let Some(shape) = state.current_shape() {
shape.set_blur(blur_type, hidden, value);
}
}
#[no_mangle]
pub extern "C" fn set_shape_path_content() {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");

View file

@ -26,6 +26,7 @@ pub trait Renderable {
fn hidden(&self) -> bool;
fn clip(&self) -> bool;
fn children_ids(&self) -> Vec<Uuid>;
fn image_filter(&self, scale: f32) -> Option<skia::ImageFilter>;
}
pub(crate) struct CachedSurfaceImage {
@ -156,15 +157,11 @@ impl RenderState {
.render(&mut self.drawing_surface, &self.images)
.unwrap();
let mut paint = skia::Paint::default();
paint.set_blend_mode(element.blend_mode().into());
paint.set_alpha_f(element.opacity());
self.drawing_surface.draw(
&mut self.final_surface.canvas(),
(0.0, 0.0),
skia::SamplingOptions::new(skia::FilterMode::Linear, skia::MipmapMode::Nearest),
Some(&paint),
Some(&skia::Paint::default()),
);
self.drawing_surface
.canvas()
@ -310,8 +307,17 @@ impl RenderState {
}
}
let mut paint = skia::Paint::default();
paint.set_blend_mode(element.blend_mode().into());
paint.set_alpha_f(element.opacity());
let filter = element.image_filter(self.viewbox.zoom * self.options.dpr());
if let Some(image_filter) = filter {
paint.set_image_filter(image_filter);
}
let layer_rec = skia::canvas::SaveLayerRec::default().paint(&paint);
// This is needed so the next non-children shape does not carry this shape's transform
self.final_surface.canvas().save();
self.final_surface.canvas().save_layer(&layer_rec);
self.drawing_surface.canvas().save();
if !root_id.is_nil() {

View file

@ -4,6 +4,7 @@ use uuid::Uuid;
use crate::render::{BlendMode, Renderable};
mod blurs;
mod bools;
mod fills;
mod images;
@ -12,6 +13,7 @@ mod paths;
mod renderable;
mod strokes;
pub use blurs::*;
pub use bools::*;
pub use fills::*;
pub use images::*;
@ -42,6 +44,7 @@ pub struct Shape {
fills: Vec<Fill>,
strokes: Vec<Stroke>,
blend_mode: BlendMode,
blur: Blur,
opacity: f32,
hidden: bool,
}
@ -61,6 +64,7 @@ impl Shape {
blend_mode: BlendMode::default(),
opacity: 1.,
hidden: false,
blur: Blur::default(),
}
}
@ -105,6 +109,10 @@ impl Shape {
self.hidden = value;
}
pub fn set_blur(&mut self, blur_type: u8, hidden: bool, value: f32) {
self.blur = Blur::new(blur_type, hidden, value);
}
pub fn add_child(&mut self, id: Uuid) {
self.children.push(id);
}

View file

@ -0,0 +1,38 @@
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum BlurType {
None,
Layer,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Blur {
pub hidden: bool,
pub blur_type: BlurType,
pub value: f32,
}
impl From<u8> for BlurType {
fn from(value: u8) -> Self {
match value {
1 => BlurType::Layer,
_ => BlurType::None,
}
}
}
impl Blur {
pub fn default() -> Self {
Blur {
blur_type: BlurType::None,
hidden: true,
value: 0.,
}
}
pub fn new(blur_type: u8, hidden: bool, value: f32) -> Self {
Blur {
blur_type: BlurType::from(blur_type),
hidden,
value,
}
}
}

View file

@ -1,7 +1,7 @@
use skia_safe as skia;
use uuid::Uuid;
use super::{Fill, Image, Kind, Path, Shape, Stroke, StrokeCap, StrokeKind};
use super::{BlurType, Fill, Image, Kind, Path, Shape, Stroke, StrokeCap, StrokeKind};
use crate::math::Rect;
use crate::render::{ImageStore, Renderable};
@ -70,6 +70,22 @@ impl Renderable for Shape {
self.children.clone()
}
}
fn image_filter(&self, scale: f32) -> Option<skia::ImageFilter> {
if !self.blur.hidden {
match self.blur.blur_type {
BlurType::None => None,
BlurType::Layer => skia::image_filters::blur(
(self.blur.value * scale, self.blur.value * scale),
None,
None,
None,
),
}
} else {
None
}
}
}
fn render_fill(