summaryrefslogtreecommitdiffstats
path: root/tiny_skia
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-02-27 02:58:02 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-02-27 02:58:02 +0100
commit37ce30f360ce7cba9ad05654e1faf26276a1dc17 (patch)
treed9d46ecc8cbf7a6b44be67ab670f43a48be16079 /tiny_skia
parent4e615a65cab9dfc5fa4a17a72580c573c1c040d9 (diff)
downloadiced-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.toml1
-rw-r--r--tiny_skia/src/backend.rs80
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,