Implement border_radius support for quads in iced_tiny_skia

This commit is contained in:
Héctor Ramón Jiménez 2023-02-27 00:47:53 +01:00
parent 53573cf7cf
commit fbb14bf9b8
No known key found for this signature in database
GPG key ID: 140CC052C94F138E

View file

@ -85,7 +85,7 @@ impl Backend {
Primitive::Quad {
bounds,
background,
border_radius: _, // TODO
border_radius,
border_width,
border_color,
} => {
@ -95,15 +95,7 @@ impl Backend {
)
.post_scale(scale_factor, scale_factor);
let path = tiny_skia::PathBuilder::from_rect(
tiny_skia::Rect::from_xywh(
bounds.x,
bounds.y,
bounds.width,
bounds.height,
)
.expect("Create quad rectangle"),
);
let path = rounded_rectangle(*bounds, *border_radius);
pixels.fill_path(
&path,
@ -223,6 +215,74 @@ fn into_color(color: Color) -> tiny_skia::Color {
.expect("Convert color from iced to tiny_skia")
}
fn rounded_rectangle(
bounds: Rectangle,
border_radius: [f32; 4],
) -> tiny_skia::Path {
let [top_left, top_right, bottom_right, bottom_left] = border_radius;
if top_left == top_right
&& top_left == bottom_right
&& top_left == bottom_left
&& top_left == bounds.width / 2.0
&& top_left == bounds.height / 2.0
{
return tiny_skia::PathBuilder::from_circle(
bounds.x + bounds.width / 2.0,
bounds.y + bounds.height / 2.0,
top_left,
)
.expect("Build circle path");
}
let mut builder = tiny_skia::PathBuilder::new();
builder.move_to(bounds.x + top_left, bounds.y);
builder.line_to(bounds.x + bounds.width - top_right, bounds.y);
if top_right > 0.0 {
builder.quad_to(
bounds.x + bounds.width,
bounds.y,
bounds.x + bounds.width,
bounds.y + top_right,
);
}
builder.line_to(
bounds.x + bounds.width,
bounds.y + bounds.height - bottom_right,
);
if bottom_right > 0.0 {
builder.quad_to(
bounds.x + bounds.width,
bounds.y + bounds.height,
bounds.x + bounds.width - bottom_right,
bounds.y + bounds.height,
);
}
builder.line_to(bounds.x + bottom_left, bounds.y + bounds.height);
if bottom_right > 0.0 {
builder.quad_to(
bounds.x,
bounds.y + bounds.height,
bounds.x,
bounds.y + bounds.height - bottom_left,
);
}
builder.line_to(bounds.x, bounds.y + top_left);
if top_left > 0.0 {
builder.quad_to(bounds.x, bounds.y, bounds.x + top_left, bounds.y);
}
builder.finish().expect("Build rounded rectangle path")
}
fn rectangular_clip_mask(
pixels: &tiny_skia::PixmapMut<'_>,
bounds: Rectangle,