Introduce Border struct analogous to Shadow

This commit is contained in:
Héctor Ramón Jiménez 2024-01-20 13:29:25 +01:00
parent 4d502012b3
commit 25f182f933
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
44 changed files with 382 additions and 424 deletions

View file

@ -152,9 +152,7 @@ impl Backend {
Primitive::Quad {
bounds,
background,
border_radius,
border_width,
border_color,
border,
shadow,
} => {
let physical_bounds = (*bounds + translation) * scale_factor;
@ -173,11 +171,12 @@ impl Backend {
.post_scale(scale_factor, scale_factor);
// Make sure the border radius is not larger than the bounds
let border_width = border_width
let border_width = border
.width
.min(bounds.width / 2.0)
.min(bounds.height / 2.0);
let mut fill_border_radius = *border_radius;
let mut fill_border_radius = <[f32; 4]>::from(border.radius);
for radius in &mut fill_border_radius {
*radius = (*radius)
.min(bounds.width / 2.0)
@ -185,92 +184,78 @@ impl Backend {
}
let path = rounded_rectangle(*bounds, fill_border_radius);
if let Some(shadow) = shadow {
if shadow.color.a > 0.0 {
let shadow_bounds = (Rectangle {
x: bounds.x + shadow.offset.x - shadow.blur_radius,
y: bounds.y + shadow.offset.y - shadow.blur_radius,
width: bounds.width + shadow.blur_radius * 2.0,
height: bounds.height + shadow.blur_radius * 2.0,
} + translation)
* scale_factor;
if shadow.color.a > 0.0 {
let shadow_bounds = (Rectangle {
x: bounds.x + shadow.offset.x - shadow.blur_radius,
y: bounds.y + shadow.offset.y - shadow.blur_radius,
width: bounds.width + shadow.blur_radius * 2.0,
height: bounds.height + shadow.blur_radius * 2.0,
} + translation)
* scale_factor;
let radii = fill_border_radius
.into_iter()
.map(|radius| radius * scale_factor)
.collect::<Vec<_>>();
let (x, y, width, height) = (
shadow_bounds.x as u32,
shadow_bounds.y as u32,
shadow_bounds.width as u32,
shadow_bounds.height as u32,
);
let half_width = physical_bounds.width / 2.0;
let half_height = physical_bounds.height / 2.0;
let radii = fill_border_radius
.into_iter()
.map(|radius| radius * scale_factor)
.collect::<Vec<_>>();
let (x, y, width, height) = (
shadow_bounds.x as u32,
shadow_bounds.y as u32,
shadow_bounds.width as u32,
shadow_bounds.height as u32,
);
let half_width = physical_bounds.width / 2.0;
let half_height = physical_bounds.height / 2.0;
let colors = (y..y + height)
.flat_map(|y| {
(x..x + width)
.map(move |x| (x as f32, y as f32))
let colors = (y..y + height)
.flat_map(|y| {
(x..x + width).map(move |x| (x as f32, y as f32))
})
.filter_map(|(x, y)| {
Size::from_wh(half_width, half_height).map(|size| {
let shadow_distance = rounded_box_sdf(
Vector::new(
x - physical_bounds.position().x
- (shadow.offset.x * scale_factor)
- half_width,
y - physical_bounds.position().y
- (shadow.offset.y * scale_factor)
- half_height,
),
size,
&radii,
);
let shadow_alpha = 1.0
- smoothstep(
-shadow.blur_radius * scale_factor,
shadow.blur_radius * scale_factor,
shadow_distance,
);
let mut color = into_color(shadow.color);
color.apply_opacity(shadow_alpha);
color.to_color_u8().premultiply()
})
.filter_map(|(x, y)| {
Size::from_wh(half_width, half_height).map(
|size| {
let shadow_distance = rounded_box_sdf(
Vector::new(
x - physical_bounds
.position()
.x
- (shadow.offset.x
* scale_factor)
- half_width,
y - physical_bounds
.position()
.y
- (shadow.offset.y
* scale_factor)
- half_height,
),
size,
&radii,
);
let shadow_alpha = 1.0
- smoothstep(
-shadow.blur_radius
* scale_factor,
shadow.blur_radius
* scale_factor,
shadow_distance,
);
})
.collect();
let mut color =
into_color(shadow.color);
color.apply_opacity(shadow_alpha);
color.to_color_u8().premultiply()
},
)
})
.collect();
if let Some(pixmap) = tiny_skia::IntSize::from_wh(
width, height,
if let Some(pixmap) = tiny_skia::IntSize::from_wh(
width, height,
)
.and_then(|size| {
tiny_skia::Pixmap::from_vec(
bytemuck::cast_vec(colors),
size,
)
.and_then(|size| {
tiny_skia::Pixmap::from_vec(
bytemuck::cast_vec(colors),
size,
)
}) {
pixels.draw_pixmap(
x as i32,
y as i32,
pixmap.as_ref(),
&tiny_skia::PixmapPaint::default(),
tiny_skia::Transform::default(),
None,
);
}
}) {
pixels.draw_pixmap(
x as i32,
y as i32,
pixmap.as_ref(),
&tiny_skia::PixmapPaint::default(),
tiny_skia::Transform::default(),
None,
);
}
}
@ -344,7 +329,7 @@ impl Backend {
};
// Make sure the border radius is correct
let mut border_radius = *border_radius;
let mut border_radius = <[f32; 4]>::from(border.radius);
let mut is_simple_border = true;
for radius in &mut border_radius {
@ -370,7 +355,7 @@ impl Backend {
&border_path,
&tiny_skia::Paint {
shader: tiny_skia::Shader::SolidColor(
into_color(*border_color),
into_color(border.color),
),
anti_alias: true,
..tiny_skia::Paint::default()
@ -426,7 +411,7 @@ impl Backend {
&border_radius_path,
&tiny_skia::Paint {
shader: tiny_skia::Shader::SolidColor(
into_color(*border_color),
into_color(border.color),
),
anti_alias: true,
..tiny_skia::Paint::default()