Allow passing a corner radius and borders to rendered images

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra
2021-09-14 17:49:11 +02:00
co-authored by Nathan Sobo
parent 96ade8668f
commit 95da665095
6 changed files with 101 additions and 50 deletions
+8
View File
@@ -657,6 +657,8 @@ impl Renderer {
for image in images {
let origin = image.bounds.origin() * scale_factor;
let target_size = image.bounds.size() * scale_factor;
let corner_radius = image.corner_radius * scale_factor;
let border_width = image.border.width * scale_factor;
let (alloc_id, atlas_bounds) = self
.prev_rendered_images
.remove(&image.data.id)
@@ -675,6 +677,12 @@ impl Renderer {
target_size: target_size.to_float2(),
source_size: atlas_bounds.size().to_float2(),
atlas_origin: atlas_bounds.origin().to_float2(),
border_top: border_width * (image.border.top as usize as f32),
border_right: border_width * (image.border.right as usize as f32),
border_bottom: border_width * (image.border.bottom as usize as f32),
border_left: border_width * (image.border.left as usize as f32),
border_color: image.border.color.to_uchar4(),
corner_radius,
});
}
+6
View File
@@ -97,4 +97,10 @@ typedef struct
vector_float2 target_size;
vector_float2 source_size;
vector_float2 atlas_origin;
float border_top;
float border_right;
float border_bottom;
float border_left;
vector_uchar4 border_color;
float corner_radius;
} GPUIImage;
+56 -45
View File
@@ -34,46 +34,19 @@ float blur_along_x(float x, float y, float sigma, float corner, float2 halfSize)
struct QuadFragmentInput {
float4 position [[position]];
vector_float2 origin;
vector_float2 size;
vector_uchar4 background_color;
float2 atlas_position; // only used in the image shader
float2 origin;
float2 size;
float4 background_color;
float border_top;
float border_right;
float border_bottom;
float border_left;
vector_uchar4 border_color;
float4 border_color;
float corner_radius;
};
vertex QuadFragmentInput quad_vertex(
uint unit_vertex_id [[vertex_id]],
uint quad_id [[instance_id]],
constant float2 *unit_vertices [[buffer(GPUIQuadInputIndexVertices)]],
constant GPUIQuad *quads [[buffer(GPUIQuadInputIndexQuads)]],
constant GPUIUniforms *uniforms [[buffer(GPUIQuadInputIndexUniforms)]]
) {
float2 unit_vertex = unit_vertices[unit_vertex_id];
GPUIQuad quad = quads[quad_id];
float2 position = unit_vertex * quad.size + quad.origin;
float4 device_position = to_device_position(position, uniforms->viewport_size);
return QuadFragmentInput {
device_position,
quad.origin,
quad.size,
quad.background_color,
quad.border_top,
quad.border_right,
quad.border_bottom,
quad.border_left,
quad.border_color,
quad.corner_radius,
};
}
fragment float4 quad_fragment(
QuadFragmentInput input [[stage_in]]
) {
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;
@@ -95,12 +68,12 @@ fragment float4 quad_fragment(
float4 color;
if (border_width == 0.) {
color = coloru_to_colorf(input.background_color);
color = input.background_color;
} else {
float inset_distance = distance + border_width;
color = mix(
coloru_to_colorf(input.border_color),
coloru_to_colorf(input.background_color),
input.border_color,
input.background_color,
saturate(0.5 - inset_distance)
);
}
@@ -109,6 +82,39 @@ fragment float4 quad_fragment(
return coverage * color;
}
vertex QuadFragmentInput quad_vertex(
uint unit_vertex_id [[vertex_id]],
uint quad_id [[instance_id]],
constant float2 *unit_vertices [[buffer(GPUIQuadInputIndexVertices)]],
constant GPUIQuad *quads [[buffer(GPUIQuadInputIndexQuads)]],
constant GPUIUniforms *uniforms [[buffer(GPUIQuadInputIndexUniforms)]]
) {
float2 unit_vertex = unit_vertices[unit_vertex_id];
GPUIQuad quad = quads[quad_id];
float2 position = unit_vertex * quad.size + quad.origin;
float4 device_position = to_device_position(position, uniforms->viewport_size);
return QuadFragmentInput {
device_position,
float2(0., 0.),
quad.origin,
quad.size,
coloru_to_colorf(quad.background_color),
quad.border_top,
quad.border_right,
quad.border_bottom,
quad.border_left,
coloru_to_colorf(quad.border_color),
quad.corner_radius,
};
}
fragment float4 quad_fragment(
QuadFragmentInput input [[stage_in]]
) {
return quad_sdf(input);
}
struct ShadowFragmentInput {
float4 position [[position]];
vector_float2 origin;
@@ -217,12 +223,7 @@ fragment float4 sprite_fragment(
return color;
}
struct ImageFragmentInput {
float4 position [[position]];
float2 atlas_position;
};
vertex ImageFragmentInput image_vertex(
vertex QuadFragmentInput image_vertex(
uint unit_vertex_id [[vertex_id]],
uint image_id [[instance_id]],
constant float2 *unit_vertices [[buffer(GPUIImageVertexInputIndexVertices)]],
@@ -236,18 +237,28 @@ vertex ImageFragmentInput image_vertex(
float4 device_position = to_device_position(position, *viewport_size);
float2 atlas_position = (unit_vertex * image.source_size + image.atlas_origin) / *atlas_size;
return ImageFragmentInput {
return QuadFragmentInput {
device_position,
atlas_position,
image.origin,
image.target_size,
float4(0.),
image.border_top,
image.border_right,
image.border_bottom,
image.border_left,
coloru_to_colorf(image.border_color),
image.corner_radius,
};
}
fragment float4 image_fragment(
ImageFragmentInput input [[stage_in]],
QuadFragmentInput input [[stage_in]],
texture2d<float> atlas [[ texture(GPUIImageFragmentInputIndexAtlas) ]]
) {
constexpr sampler atlas_sampler(mag_filter::linear, min_filter::linear);
return atlas.sample(atlas_sampler, input.atlas_position);
input.background_color = atlas.sample(atlas_sampler, input.atlas_position);
return quad_sdf(input);
}
struct PathAtlasVertexOutput {