diff options
author | 2023-02-27 02:58:02 +0100 | |
---|---|---|
committer | 2023-02-27 02:58:02 +0100 | |
commit | 37ce30f360ce7cba9ad05654e1faf26276a1dc17 (patch) | |
tree | d9d46ecc8cbf7a6b44be67ab670f43a48be16079 /tiny_skia | |
parent | 4e615a65cab9dfc5fa4a17a72580c573c1c040d9 (diff) | |
download | iced-37ce30f360ce7cba9ad05654e1faf26276a1dc17.tar.gz iced-37ce30f360ce7cba9ad05654e1faf26276a1dc17.tar.bz2 iced-37ce30f360ce7cba9ad05654e1faf26276a1dc17.zip |
Use `kurbo` to approximate arcs in `iced_tiny_skia`
Diffstat (limited to 'tiny_skia')
-rw-r--r-- | tiny_skia/Cargo.toml | 1 | ||||
-rw-r--r-- | tiny_skia/src/backend.rs | 80 |
2 files changed, 71 insertions, 10 deletions
diff --git a/tiny_skia/Cargo.toml b/tiny_skia/Cargo.toml index 55f7f5b7..7fee49cb 100644 --- a/tiny_skia/Cargo.toml +++ b/tiny_skia/Cargo.toml @@ -14,6 +14,7 @@ tiny-skia = "0.8" bytemuck = "1" rustc-hash = "1.1" ouroboros = "0.15" +kurbo = "0.9" [dependencies.iced_native] version = "0.9" diff --git a/tiny_skia/src/backend.rs b/tiny_skia/src/backend.rs index b1dd6a46..38a6c51d 100644 --- a/tiny_skia/src/backend.rs +++ b/tiny_skia/src/backend.rs @@ -241,48 +241,108 @@ fn rounded_rectangle( builder.line_to(bounds.x + bounds.width - top_right, bounds.y); if top_right > 0.0 { - builder.quad_to( - bounds.x + bounds.width, + arc_to( + &mut builder, + bounds.x + bounds.width - top_right, bounds.y, bounds.x + bounds.width, bounds.y + top_right, + top_right, ); } - builder.line_to( + maybe_line_to( + &mut builder, bounds.x + bounds.width, bounds.y + bounds.height - bottom_right, ); if bottom_right > 0.0 { - builder.quad_to( + arc_to( + &mut builder, bounds.x + bounds.width, - bounds.y + bounds.height, + bounds.y + bounds.height - bottom_right, bounds.x + bounds.width - bottom_right, bounds.y + bounds.height, + bottom_right, ); } - builder.line_to(bounds.x + bottom_left, bounds.y + bounds.height); + maybe_line_to( + &mut builder, + bounds.x + bottom_left, + bounds.y + bounds.height, + ); if bottom_right > 0.0 { - builder.quad_to( - bounds.x, + arc_to( + &mut builder, + bounds.x + bottom_left, bounds.y + bounds.height, bounds.x, bounds.y + bounds.height - bottom_left, + bottom_left, ); } - builder.line_to(bounds.x, bounds.y + top_left); + maybe_line_to(&mut builder, bounds.x, bounds.y + top_left); if top_left > 0.0 { - builder.quad_to(bounds.x, bounds.y, bounds.x + top_left, bounds.y); + arc_to( + &mut builder, + bounds.x, + bounds.y + top_left, + bounds.x + top_left, + bounds.y, + top_left, + ); } builder.finish().expect("Build rounded rectangle path") } +fn maybe_line_to(path: &mut tiny_skia::PathBuilder, x: f32, y: f32) { + if path.last_point() != Some(tiny_skia::Point { x, y }) { + path.line_to(x, y); + } +} + +fn arc_to( + path: &mut tiny_skia::PathBuilder, + x_from: f32, + y_from: f32, + x_to: f32, + y_to: f32, + radius: f32, +) { + let svg_arc = kurbo::SvgArc { + from: kurbo::Point::new(f64::from(x_from), f64::from(y_from)), + to: kurbo::Point::new(f64::from(x_to), f64::from(y_to)), + radii: kurbo::Vec2::new(f64::from(radius), f64::from(radius)), + x_rotation: 0.0, + large_arc: false, + sweep: true, + }; + + match kurbo::Arc::from_svg_arc(&svg_arc) { + Some(arc) => { + arc.to_cubic_beziers(0.1, |p1, p2, p| { + path.cubic_to( + p1.x as f32, + p1.y as f32, + p2.x as f32, + p2.y as f32, + p.x as f32, + p.y as f32, + ); + }); + } + None => { + path.line_to(x_to as f32, y_to as f32); + } + } +} + fn rectangular_clip_mask( pixels: &tiny_skia::PixmapMut<'_>, bounds: Rectangle, |