Wire up per corner radii for quad

Still need to expose this in the styling layer and allow images
to have per corner radii.
This commit is contained in:
Nathan Sobo 2023-08-12 10:40:23 -06:00
parent 1911f537b4
commit 84dc4090bd
13 changed files with 205 additions and 36 deletions

View file

@ -248,7 +248,7 @@ impl<V: View> Element<V> for Container<V> {
bounds: quad_bounds,
background: self.style.background_color,
border: Default::default(),
corner_radius: self.style.corner_radius,
corner_radii: self.style.corner_radius.into(),
});
self.child
@ -259,7 +259,7 @@ impl<V: View> Element<V> for Container<V> {
bounds: quad_bounds,
background: self.style.overlay_color,
border: self.style.border,
corner_radius: self.style.corner_radius,
corner_radii: self.style.corner_radius.into(),
});
scene.pop_layer();
} else {
@ -267,7 +267,7 @@ impl<V: View> Element<V> for Container<V> {
bounds: quad_bounds,
background: self.style.background_color,
border: self.style.border,
corner_radius: self.style.corner_radius,
corner_radii: self.style.corner_radius.into(),
});
let child_origin = child_origin
@ -284,7 +284,7 @@ impl<V: View> Element<V> for Container<V> {
bounds: quad_bounds,
background: self.style.overlay_color,
border: Default::default(),
corner_radius: 0.,
corner_radii: self.style.corner_radius.into(),
});
scene.pop_layer();
}

View file

@ -586,7 +586,10 @@ impl Renderer {
border_bottom: border_width * (quad.border.bottom as usize as f32),
border_left: border_width * (quad.border.left as usize as f32),
border_color: quad.border.color.to_uchar4(),
corner_radius: quad.corner_radius * scale_factor,
corner_radius_top_left: quad.corner_radii.top_left * scale_factor,
corner_radius_top_right: quad.corner_radii.top_right * scale_factor,
corner_radius_bottom_right: quad.corner_radii.bottom_right * scale_factor,
corner_radius_bottom_left: quad.corner_radii.bottom_left * scale_factor,
};
unsafe {
*(buffer_contents.add(ix)) = shader_quad;

View file

@ -19,7 +19,10 @@ typedef struct {
float border_bottom;
float border_left;
vector_uchar4 border_color;
float corner_radius;
float corner_radius_top_left;
float corner_radius_top_right;
float corner_radius_bottom_right;
float corner_radius_bottom_left;
} GPUIQuad;
typedef enum {

View file

@ -43,7 +43,10 @@ struct QuadFragmentInput {
float border_bottom;
float border_left;
float4 border_color;
float corner_radius;
float corner_radius_top_left;
float corner_radius_top_right;
float corner_radius_bottom_right;
float corner_radius_bottom_left;
uchar grayscale; // only used in image shader
};
@ -51,12 +54,27 @@ float4 quad_sdf(QuadFragmentInput input) {
float2 half_size = input.size / 2.;
float2 center = input.origin + half_size;
float2 center_to_point = input.position.xy - center;
float2 rounded_edge_to_point = abs(center_to_point) - half_size + input.corner_radius;
float distance = length(max(0., rounded_edge_to_point)) + min(0., max(rounded_edge_to_point.x, rounded_edge_to_point.y)) - input.corner_radius;
float corner_radius;
if (center_to_point.x < 0.) {
if (center_to_point.y < 0.) {
corner_radius = input.corner_radius_top_left;
} else {
corner_radius = input.corner_radius_bottom_left;
}
} else {
if (center_to_point.y < 0.) {
corner_radius = input.corner_radius_top_right;
} else {
corner_radius = input.corner_radius_bottom_right;
}
}
float2 rounded_edge_to_point = abs(center_to_point) - half_size + corner_radius;
float distance = length(max(0., rounded_edge_to_point)) + min(0., max(rounded_edge_to_point.x, rounded_edge_to_point.y)) - corner_radius;
float vertical_border = center_to_point.x <= 0. ? input.border_left : input.border_right;
float horizontal_border = center_to_point.y <= 0. ? input.border_top : input.border_bottom;
float2 inset_size = half_size - input.corner_radius - float2(vertical_border, horizontal_border);
float2 inset_size = half_size - corner_radius - float2(vertical_border, horizontal_border);
float2 point_to_inset_corner = abs(center_to_point) - inset_size;
float border_width;
if (point_to_inset_corner.x < 0. && point_to_inset_corner.y < 0.) {
@ -110,7 +128,10 @@ vertex QuadFragmentInput quad_vertex(
quad.border_bottom,
quad.border_left,
coloru_to_colorf(quad.border_color),
quad.corner_radius,
quad.corner_radius_top_left,
quad.corner_radius_top_right,
quad.corner_radius_bottom_right,
quad.corner_radius_bottom_left,
0,
};
}
@ -253,6 +274,9 @@ vertex QuadFragmentInput image_vertex(
image.border_left,
coloru_to_colorf(image.border_color),
image.corner_radius,
image.corner_radius,
image.corner_radius,
image.corner_radius,
image.grayscale,
};
}
@ -266,7 +290,7 @@ fragment float4 image_fragment(
if (input.grayscale) {
float grayscale =
0.2126 * input.background_color.r +
0.7152 * input.background_color.g +
0.7152 * input.background_color.g +
0.0722 * input.background_color.b;
input.background_color = float4(grayscale, grayscale, grayscale, input.background_color.a);
}

View file

@ -65,7 +65,26 @@ pub struct Quad {
pub bounds: RectF,
pub background: Option<Color>,
pub border: Border,
pub corner_radius: f32,
pub corner_radii: CornerRadii,
}
#[derive(Default, Debug)]
pub struct CornerRadii {
pub top_left: f32,
pub top_right: f32,
pub bottom_right: f32,
pub bottom_left: f32,
}
impl From<f32> for CornerRadii {
fn from(radius: f32) -> Self {
Self {
top_left: radius,
top_right: radius,
bottom_right: radius,
bottom_left: radius,
}
}
}
#[derive(Debug)]