Skip transparent shadows in iced_tiny_skia

This commit is contained in:
Héctor Ramón Jiménez 2024-01-20 12:39:41 +01:00
parent 370b2f6df7
commit 4d502012b3
No known key found for this signature in database
GPG key ID: 7CC46565708259A7

View file

@ -186,33 +186,7 @@ impl Backend {
let path = rounded_rectangle(*bounds, fill_border_radius); let path = rounded_rectangle(*bounds, fill_border_radius);
if let Some(shadow) = shadow { if let Some(shadow) = shadow {
fn smoothstep(a: f32, b: f32, x: f32) -> f32 { if shadow.color.a > 0.0 {
let x = ((x - a) / (b - a)).clamp(0.0, 1.0);
x * x * (3.0 - 2.0 * x)
}
fn rounded_box_sdf(
to_center: Vector,
size: Size,
radii: &[f32],
) -> f32 {
let radius =
match (to_center.x > 0.0, to_center.y > 0.0) {
(true, true) => radii[2],
(true, false) => radii[1],
(false, true) => radii[3],
(false, false) => radii[0],
};
let x = (to_center.x.abs() - size.width() + radius)
.max(0.0);
let y = (to_center.y.abs() - size.height() + radius)
.max(0.0);
(x.powf(2.0) + y.powf(2.0)).sqrt() - radius
}
let shadow_bounds = (Rectangle { let shadow_bounds = (Rectangle {
x: bounds.x + shadow.offset.x - shadow.blur_radius, x: bounds.x + shadow.offset.x - shadow.blur_radius,
y: bounds.y + shadow.offset.y - shadow.blur_radius, y: bounds.y + shadow.offset.y - shadow.blur_radius,
@ -236,17 +210,25 @@ impl Backend {
let colors = (y..y + height) let colors = (y..y + height)
.flat_map(|y| { .flat_map(|y| {
(x..x + width).map(move |x| (x as f32, y as f32)) (x..x + width)
.map(move |x| (x as f32, y as f32))
}) })
.filter_map(|(x, y)| { .filter_map(|(x, y)| {
Size::from_wh(half_width, half_height).map(|size| { Size::from_wh(half_width, half_height).map(
|size| {
let shadow_distance = rounded_box_sdf( let shadow_distance = rounded_box_sdf(
Vector::new( Vector::new(
x - physical_bounds.position().x x - physical_bounds
- (shadow.offset.x * scale_factor) .position()
.x
- (shadow.offset.x
* scale_factor)
- half_width, - half_width,
y - physical_bounds.position().y y - physical_bounds
- (shadow.offset.y * scale_factor) .position()
.y
- (shadow.offset.y
* scale_factor)
- half_height, - half_height,
), ),
size, size,
@ -254,16 +236,20 @@ impl Backend {
); );
let shadow_alpha = 1.0 let shadow_alpha = 1.0
- smoothstep( - smoothstep(
-shadow.blur_radius * scale_factor, -shadow.blur_radius
shadow.blur_radius * scale_factor, * scale_factor,
shadow.blur_radius
* scale_factor,
shadow_distance, shadow_distance,
); );
let mut color = into_color(shadow.color); let mut color =
into_color(shadow.color);
color.apply_opacity(shadow_alpha); color.apply_opacity(shadow_alpha);
color.to_color_u8().premultiply() color.to_color_u8().premultiply()
}) },
)
}) })
.collect(); .collect();
@ -286,6 +272,7 @@ impl Backend {
); );
} }
} }
}
pixels.fill_path( pixels.fill_path(
&path, &path,
@ -969,6 +956,26 @@ fn adjust_clip_mask(clip_mask: &mut tiny_skia::Mask, bounds: Rectangle) {
); );
} }
fn smoothstep(a: f32, b: f32, x: f32) -> f32 {
let x = ((x - a) / (b - a)).clamp(0.0, 1.0);
x * x * (3.0 - 2.0 * x)
}
fn rounded_box_sdf(to_center: Vector, size: Size, radii: &[f32]) -> f32 {
let radius = match (to_center.x > 0.0, to_center.y > 0.0) {
(true, true) => radii[2],
(true, false) => radii[1],
(false, true) => radii[3],
(false, false) => radii[0],
};
let x = (to_center.x.abs() - size.width() + radius).max(0.0);
let y = (to_center.y.abs() - size.height() + radius).max(0.0);
(x.powf(2.0) + y.powf(2.0)).sqrt() - radius
}
impl iced_graphics::Backend for Backend { impl iced_graphics::Backend for Backend {
type Primitive = primitive::Custom; type Primitive = primitive::Custom;
} }