Make shadow optional in renderer::Quad

This commit is contained in:
Héctor Ramón Jiménez 2024-01-20 12:11:18 +01:00
parent 83902921a3
commit b7b457a575
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
8 changed files with 57 additions and 46 deletions

View file

@ -5,7 +5,7 @@ mod null;
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
pub use null::Null; pub use null::Null;
use crate::{Background, BorderRadius, Color, Rectangle, Shadow, Vector}; use crate::{Background, BorderRadius, Color, Rectangle, Shadow, Size, Vector};
/// A component that can be used by widgets to draw themselves on a screen. /// A component that can be used by widgets to draw themselves on a screen.
pub trait Renderer: Sized { pub trait Renderer: Sized {
@ -47,7 +47,19 @@ pub struct Quad {
pub border_color: Color, pub border_color: Color,
/// The shadow of the [`Quad`]. /// The shadow of the [`Quad`].
pub shadow: Shadow, pub shadow: Option<Shadow>,
}
impl Default for Quad {
fn default() -> Self {
Self {
bounds: Rectangle::with_size(Size::ZERO),
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
shadow: None,
}
}
} }
/// The styling attributes of a [`Renderer`]. /// The styling attributes of a [`Renderer`].

View file

@ -2,7 +2,7 @@
use crate::{Color, Vector}; use crate::{Color, Vector};
/// A shadow /// A shadow
#[derive(Debug, Clone, Copy, PartialEq, Default)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct Shadow { pub struct Shadow {
/// The color of the shadow /// The color of the shadow
pub color: Color, pub color: Color,
@ -10,6 +10,6 @@ pub struct Shadow {
/// The offset of the shadow /// The offset of the shadow
pub offset: Vector, pub offset: Vector,
/// The blur_radius of the shadow /// The blur radius of the shadow
pub blur_radius: f32, pub blur_radius: f32,
} }

View file

@ -65,7 +65,7 @@ mod quad {
border_radius: self.radius.into(), border_radius: self.radius.into(),
border_width: self.border_width, border_width: self.border_width,
border_color: Color::from_rgb(1.0, 0.0, 0.0), border_color: Color::from_rgb(1.0, 0.0, 0.0),
shadow: self.shadow, shadow: Some(self.shadow),
}, },
Color::BLACK, Color::BLACK,
); );

View file

@ -80,26 +80,25 @@ impl<T: Damage> Damage for Primitive<T> {
} }
Self::Quad { Self::Quad {
bounds, bounds,
shadow_offset, shadow: Some(shadow),
shadow_blur_radius,
.. ..
} => { } => {
let bounds_with_shadow = Rectangle { let bounds_with_shadow = Rectangle {
x: bounds.x + shadow_offset.x.min(0.0) - shadow_blur_radius, x: bounds.x + shadow.offset.x.min(0.0) - shadow.blur_radius,
y: bounds.y + shadow_offset.y.min(0.0) - shadow_blur_radius, y: bounds.y + shadow.offset.y.min(0.0) - shadow.blur_radius,
width: bounds.width width: bounds.width
+ shadow_offset.x.abs() + shadow.offset.x.abs()
+ shadow_blur_radius * 2.0, + shadow.blur_radius * 2.0,
height: bounds.height height: bounds.height
+ shadow_offset.y.abs() + shadow.offset.y.abs()
+ shadow_blur_radius * 2.0, + shadow.blur_radius * 2.0,
}; };
bounds_with_shadow.expand(1.0) bounds_with_shadow.expand(1.0)
} }
Self::Image { bounds, .. } | Self::Svg { bounds, .. } => { Self::Quad { bounds, .. }
bounds.expand(1.0) | Self::Image { bounds, .. }
} | Self::Svg { bounds, .. } => bounds.expand(1.0),
Self::Clip { bounds, .. } => bounds.expand(1.0), Self::Clip { bounds, .. } => bounds.expand(1.0),
Self::Group { primitives } => primitives Self::Group { primitives } => primitives
.iter() .iter()

View file

@ -3,7 +3,9 @@ use crate::core::alignment;
use crate::core::image; use crate::core::image;
use crate::core::svg; use crate::core::svg;
use crate::core::text; use crate::core::text;
use crate::core::{Background, Color, Font, Pixels, Point, Rectangle, Vector}; use crate::core::{
Background, Color, Font, Pixels, Point, Rectangle, Shadow, Vector,
};
use crate::text::editor; use crate::text::editor;
use crate::text::paragraph; use crate::text::paragraph;
@ -71,12 +73,8 @@ pub enum Primitive<T> {
border_width: f32, border_width: f32,
/// The border color of the quad /// The border color of the quad
border_color: Color, border_color: Color,
/// The shadow color of the quad /// The [`Shadow`] of the quad
shadow_color: Color, shadow: Option<Shadow>,
/// The shadow offset of the quad
shadow_offset: Vector,
/// The shadow blur radius of the quad
shadow_blur_radius: f32,
}, },
/// An image primitive /// An image primitive
Image { Image {

View file

@ -127,9 +127,7 @@ impl<B: Backend, T> iced_core::Renderer for Renderer<B, T> {
border_radius: quad.border_radius.into(), border_radius: quad.border_radius.into(),
border_width: quad.border_width, border_width: quad.border_width,
border_color: quad.border_color, border_color: quad.border_color,
shadow_color: quad.shadow.color, shadow: quad.shadow,
shadow_offset: quad.shadow.offset,
shadow_blur_radius: quad.shadow.blur_radius,
}); });
} }

View file

@ -155,9 +155,7 @@ impl Backend {
border_radius, border_radius,
border_width, border_width,
border_color, border_color,
shadow_color, shadow,
shadow_offset,
shadow_blur_radius,
} => { } => {
let physical_bounds = (*bounds + translation) * scale_factor; let physical_bounds = (*bounds + translation) * scale_factor;
@ -187,7 +185,7 @@ impl Backend {
} }
let path = rounded_rectangle(*bounds, fill_border_radius); let path = rounded_rectangle(*bounds, fill_border_radius);
if shadow_color.a > 0.0 { if let Some(shadow) = shadow {
fn smoothstep(a: f32, b: f32, x: f32) -> f32 { fn smoothstep(a: f32, b: f32, x: f32) -> f32 {
let x = ((x - a) / (b - a)).clamp(0.0, 1.0); let x = ((x - a) / (b - a)).clamp(0.0, 1.0);
@ -216,10 +214,10 @@ impl Backend {
} }
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,
width: bounds.width + shadow_blur_radius * 2.0, width: bounds.width + shadow.blur_radius * 2.0,
height: bounds.height + shadow_blur_radius * 2.0, height: bounds.height + shadow.blur_radius * 2.0,
} + translation) } + translation)
* scale_factor; * scale_factor;
@ -245,10 +243,10 @@ impl Backend {
let shadow_distance = rounded_box_sdf( let shadow_distance = rounded_box_sdf(
Vector::new( Vector::new(
x - physical_bounds.position().x x - physical_bounds.position().x
- (shadow_offset.x * scale_factor) - (shadow.offset.x * scale_factor)
- half_width, - half_width,
y - physical_bounds.position().y y - physical_bounds.position().y
- (shadow_offset.y * scale_factor) - (shadow.offset.y * scale_factor)
- half_height, - half_height,
), ),
size, size,
@ -256,12 +254,12 @@ impl Backend {
); );
let shadow_alpha = 1.0 let shadow_alpha = 1.0
- smoothstep( - smoothstep(
-shadow_blur_radius * scale_factor, -shadow.blur_radius * scale_factor,
*shadow_blur_radius * 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()

View file

@ -12,7 +12,9 @@ pub use text::Text;
use crate::core; use crate::core;
use crate::core::alignment; use crate::core::alignment;
use crate::core::{Color, Font, Pixels, Point, Rectangle, Size, Vector}; use crate::core::{
Color, Font, Pixels, Point, Rectangle, Shadow, Size, Vector,
};
use crate::graphics; use crate::graphics;
use crate::graphics::color; use crate::graphics::color;
use crate::graphics::Viewport; use crate::graphics::Viewport;
@ -198,12 +200,16 @@ impl<'a> Layer<'a> {
border_radius, border_radius,
border_width, border_width,
border_color, border_color,
shadow_color, shadow,
shadow_offset,
shadow_blur_radius,
} => { } => {
let layer = &mut layers[current_layer]; let layer = &mut layers[current_layer];
let shadow = shadow.unwrap_or_else(|| Shadow {
color: Color::TRANSPARENT,
offset: Vector::ZERO,
blur_radius: 0.0,
});
let quad = Quad { let quad = Quad {
position: [ position: [
bounds.x + translation.x, bounds.x + translation.x,
@ -213,9 +219,9 @@ impl<'a> Layer<'a> {
border_color: color::pack(*border_color), border_color: color::pack(*border_color),
border_radius: *border_radius, border_radius: *border_radius,
border_width: *border_width, border_width: *border_width,
shadow_color: shadow_color.into_linear(), shadow_color: shadow.color.into_linear(),
shadow_offset: (*shadow_offset).into(), shadow_offset: shadow.offset.into(),
shadow_blur_radius: *shadow_blur_radius, shadow_blur_radius: shadow.blur_radius,
}; };
layer.quads.add(quad, background); layer.quads.add(quad, background);