Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support individual corner radii for kurbo::RoundedRect #391

Merged
merged 11 commits into from
Feb 9, 2021
10 changes: 5 additions & 5 deletions piet-direct2d/src/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use winapi::um::d2d1::{
D2D1_MATRIX_3X2_F, D2D1_POINT_2F, D2D1_RECT_F, D2D1_ROUNDED_RECT, D2D1_STROKE_STYLE_PROPERTIES,
};

use piet::kurbo::{Affine, Circle, Point, Rect, RoundedRect, Vec2};
use piet::kurbo::{Affine, Circle, Point, Rect, Vec2};

use piet::{Color, Error, GradientStop, LineCap, LineJoin, RoundFrom, RoundInto, StrokeStyle};

Expand Down Expand Up @@ -98,11 +98,11 @@ pub(crate) fn rect_to_rectf(rect: Rect) -> D2D1_RECT_F {
}
}

pub(crate) fn rounded_rect_to_d2d(round_rect: RoundedRect) -> D2D1_ROUNDED_RECT {
pub(crate) fn rounded_rect_to_d2d(rect: Rect, radius: f64) -> D2D1_ROUNDED_RECT {
D2D1_ROUNDED_RECT {
rect: rect_to_rectf(round_rect.rect()),
radiusX: round_rect.radius() as f32,
radiusY: round_rect.radius() as f32,
rect: rect_to_rectf(rect),
radiusX: radius as f32,
radiusY: radius as f32,
}
}

Expand Down
18 changes: 11 additions & 7 deletions piet-direct2d/src/d2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,15 +267,16 @@ impl D2DFactory {

pub fn create_round_rect_geometry(
&self,
rect: RoundedRect,
rect: Rect,
radius: f64,
) -> Result<RoundedRectangleGeometry, Error> {
unsafe {
let mut ptr = null_mut();
let hr = self
.0
.deref()
.deref()
.CreateRoundedRectangleGeometry(&rounded_rect_to_d2d(rect), &mut ptr);
.CreateRoundedRectangleGeometry(&rounded_rect_to_d2d(rect, radius), &mut ptr);
wrap(hr, ptr, RoundedRectangleGeometry)
}
}
Expand Down Expand Up @@ -517,15 +518,17 @@ impl DeviceContext {
}

pub(crate) fn draw_rounded_rect(
&self,
rect: RoundedRect,
&mut self,
rect: Rect,
radius: f64,
brush: &Brush,
width: f32,
style: Option<&StrokeStyle>,
) {
let d2d_rounded_rect = rounded_rect_to_d2d(rect, radius);
unsafe {
self.0.DrawRoundedRectangle(
&rounded_rect_to_d2d(rect),
&d2d_rounded_rect,
brush.as_raw(),
width,
stroke_style_to_d2d(style),
Expand Down Expand Up @@ -556,10 +559,11 @@ impl DeviceContext {
}
}

pub(crate) fn fill_rounded_rect(&self, rect: RoundedRect, brush: &Brush) {
pub(crate) fn fill_rounded_rect(&mut self, rect: Rect, radius: f64, brush: &Brush) {
let d2d_rounded_rect = rounded_rect_to_d2d(rect, radius);
unsafe {
self.0
.FillRoundedRectangle(&rounded_rect_to_d2d(rect), brush.as_raw());
.FillRoundedRectangle(&d2d_rounded_rect, brush.as_raw());
}
}

Expand Down
58 changes: 40 additions & 18 deletions piet-direct2d/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,16 @@ fn geometry_from_shape(
// TODO: Do something special for line?
if let Some(rect) = shape.as_rect() {
Ok(d2d.create_rect_geometry(rect)?.into())
} else if let Some(round_rect) = shape.as_rounded_rect() {
Ok(d2d.create_round_rect_geometry(round_rect)?.into())
} else if let Some(round_rect) = shape
.as_rounded_rect()
.filter(|r| r.radii().as_single_radius().is_some())
{
Ok(d2d
.create_round_rect_geometry(
round_rect.rect(),
round_rect.radii().as_single_radius().unwrap(),
)?
.into())
} else if let Some(circle) = shape.as_circle() {
Ok(d2d.create_circle_geometry(circle)?.into())
} else {
Expand Down Expand Up @@ -431,8 +439,15 @@ impl<'a> D2DRenderContext<'a> {
// TODO: do something special (or nothing at all) for line?
if let Some(rect) = shape.as_rect() {
self.rt.fill_rect(rect, &brush)
} else if let Some(round_rect) = shape.as_rounded_rect() {
self.rt.fill_rounded_rect(round_rect, &brush)
} else if let Some(round_rect) = shape
.as_rounded_rect()
.filter(|r| r.radii().as_single_radius().is_some())
{
self.rt.fill_rounded_rect(
round_rect.rect(),
round_rect.radii().as_single_radius().unwrap(),
&brush,
)
} else if let Some(circle) = shape.as_circle() {
self.rt.fill_circle(circle, &brush)
} else {
Expand All @@ -454,24 +469,31 @@ impl<'a> D2DRenderContext<'a> {
let width = width as f32;

if let Some(line) = shape.as_line() {
self.rt.draw_line(line, &brush, width, style)
self.rt.draw_line(line, &brush, width, style);
return;
} else if let Some(rect) = shape.as_rect() {
self.rt.draw_rect(rect, &brush, width, style)
self.rt.draw_rect(rect, &brush, width, style);
return;
} else if let Some(round_rect) = shape.as_rounded_rect() {
self.rt.draw_rounded_rect(round_rect, &brush, width, style)
if let Some(radius) = round_rect.radii().as_single_radius() {
self.rt
.draw_rounded_rect(round_rect.rect(), radius, &brush, width, style);
return;
}
} else if let Some(circle) = shape.as_circle() {
self.rt.draw_circle(circle, &brush, width, style)
} else {
let geom = match path_from_shape(self.factory, false, shape, FillRule::EvenOdd) {
Ok(geom) => geom,
Err(e) => {
self.err = Err(e);
return;
}
};
let width = width;
self.rt.draw_geometry(&geom, &*brush, width, style);
self.rt.draw_circle(circle, &brush, width, style);
return;
}

let geom = match path_from_shape(self.factory, false, shape, FillRule::EvenOdd) {
Ok(geom) => geom,
Err(e) => {
self.err = Err(e);
return;
}
};
let width = width;
self.rt.draw_geometry(&geom, &*brush, width, style);
}

// This is split out to unify error reporting, as there are lots of opportunities for
Expand Down
19 changes: 11 additions & 8 deletions piet-svg/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,14 +370,17 @@ fn add_shape(node: &mut impl Node, shape: impl Shape, attrs: &Attrs) {
.set("r", circle.radius);
attrs.apply_to(&mut x);
node.append(x);
} else if let Some(rect) = shape.as_rounded_rect() {
} else if let Some(round_rect) = shape
.as_rounded_rect()
.filter(|r| r.radii().as_single_radius().is_some())
{
let mut x = svg::node::element::Rectangle::new()
.set("x", rect.origin().x)
.set("y", rect.origin().y)
.set("width", rect.width())
.set("height", rect.height())
.set("rx", rect.radius())
.set("ry", rect.radius());
.set("x", round_rect.origin().x)
.set("y", round_rect.origin().y)
.set("width", round_rect.width())
.set("height", round_rect.height())
.set("rx", round_rect.radii().as_single_radius().unwrap())
.set("ry", round_rect.radii().as_single_radius().unwrap());
attrs.apply_to(&mut x);
node.append(x);
} else if let Some(rect) = shape.as_rect() {
Expand All @@ -391,7 +394,7 @@ fn add_shape(node: &mut impl Node, shape: impl Shape, attrs: &Attrs) {
} else {
let mut path = svg::node::element::Path::new().set("d", shape.into_path(1e-3).to_svg());
attrs.apply_to(&mut path);
node.append(path)
node.append(path);
}
}

Expand Down
6 changes: 3 additions & 3 deletions piet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ include = ["src/**/*", "Cargo.toml", "snapshots/resources/*"]

[dependencies]
image = { version = "0.23.10", optional = true, default-features = false }
kurbo = "0.7.0"
pico-args = { version = "0.3.3", optional = true }
png = {version = "0.16.2", optional = true }
kurbo = "0.8.0"
pico-args = { version = "0.3.3", optional = true }
png = { version = "0.16.2", optional = true }
os_info = { version = "3.0.0", optional = true, default-features = false }
unic-bidi = "0.9"

Expand Down
13 changes: 12 additions & 1 deletion piet/src/samples/picture_6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub fn draw<R: RenderContext>(rc: &mut R) -> Result<(), Error> {
stops: create_gradient_stops(),
}))?;
rc.stroke_styled(
RoundedRect::new(60.0, 0.0, 100.0, 30.0, 7.0),
RoundedRect::new(60.0, 0.0, 100.0, 30.0, (7.0, 7.0, 7.0, 15.0)),
&linear_gradient,
5.0,
&stroke_style,
Expand All @@ -56,6 +56,17 @@ pub fn draw<R: RenderContext>(rc: &mut R) -> Result<(), Error> {
);
rc.stroke(Rect::new(60.0, 80.0, 100.0, 100.0), &linear_gradient, 4.0);

rc.fill(
RoundedRect::new(115.0, 10.0, 165.0, 40.0, (15.0, 2.0, 2.0, 2.0)),
&linear_gradient,
);

rc.stroke(
RoundedRect::new(115.0, 50.0, 165.0, 80.0, (2.0, 2.0, 15.0, 2.0)),
&linear_gradient,
4.0,
);

Ok(())
}

Expand Down