Checkpoint

This commit is contained in:
Antonio Scandurra 2023-10-04 18:38:08 +02:00
parent 133c3a330c
commit 5aa45607eb
5 changed files with 25 additions and 57 deletions

View file

@ -1,6 +1,6 @@
use crate::{
BorrowWindow, ContentMask, Element, IsZero, Layout, LayoutId, Result, SharedString, Style,
StyleHelpers, Styled, ViewContext,
BorrowWindow, Element, Layout, LayoutId, Result, SharedString, Style, StyleHelpers, Styled,
ViewContext,
};
use futures::FutureExt;
use refineable::RefinementCascade;
@ -73,17 +73,7 @@ impl<S: 'static> Element for Img<S> {
.and_then(ResultExt::log_err)
{
let corner_radii = style.corner_radii.to_pixels(bounds, cx.rem_size());
if corner_radii.is_zero() {
cx.paint_image(bounds, order, data, self.grayscale)?;
} else {
cx.with_content_mask(
ContentMask {
bounds,
corner_radii,
},
|cx| cx.paint_image(bounds, order, data, self.grayscale),
)?;
}
cx.paint_image(bounds, corner_radii, order, data, self.grayscale)?;
} else {
log::warn!("image not loaded yet");
// cx.spawn(|this, mut cx| async move {

View file

@ -106,11 +106,7 @@ fragment float4 quad_fragment(QuadVertexOutput input [[stage_in]],
color = float4(premultiplied_output_rgb, output_alpha);
}
float clip_distance =
quad_sdf(input.position.xy, quad.clip_bounds, quad.clip_corner_radii);
return color *
float4(1., 1., 1.,
saturate(0.5 - distance) * saturate(0.5 - clip_distance));
return color * float4(1., 1., 1., saturate(0.5 - distance));
}
struct MonochromeSpriteVertexOutput {
@ -131,8 +127,9 @@ vertex MonochromeSpriteVertexOutput monochrome_sprite_vertex(
float2 unit_vertex = unit_vertices[unit_vertex_id];
MonochromeSprite sprite = sprites[sprite_id];
// Don't apply content mask at the vertex level because we don't have time to make sampling from the texture match the mask.
float4 device_position = to_device_position(
unit_vertex, sprite.bounds, sprite.content_mask.bounds, viewport_size);
unit_vertex, sprite.bounds, sprite.bounds, viewport_size);
float2 tile_position = to_tile_position(unit_vertex, sprite.tile, atlas_size);
float4 color = hsla_to_rgba(sprite.color);
return MonochromeSpriteVertexOutput{device_position, tile_position, color,
@ -148,8 +145,11 @@ fragment float4 monochrome_sprite_fragment(
min_filter::linear);
float4 sample =
atlas_texture.sample(atlas_texture_sampler, input.tile_position);
float clip_distance = quad_sdf(input.position.xy, sprite.content_mask.bounds,
sprite.content_mask.corner_radii);
float clip_distance = quad_sdf(
input.position.xy,
sprite.content_mask.bounds,
Corners_ScaledPixels { 0., 0., 0., 0. }
);
float4 color = input.color;
color.a *= sample.a * saturate(0.5 - clip_distance);
return color;
@ -172,8 +172,9 @@ vertex PolychromeSpriteVertexOutput polychrome_sprite_vertex(
float2 unit_vertex = unit_vertices[unit_vertex_id];
PolychromeSprite sprite = sprites[sprite_id];
// Don't apply content mask at the vertex level because we don't have time to make sampling from the texture match the mask.
float4 device_position = to_device_position(
unit_vertex, sprite.bounds, sprite.content_mask.bounds, viewport_size);
unit_vertex, sprite.bounds, sprite.bounds, viewport_size);
float2 tile_position = to_tile_position(unit_vertex, sprite.tile, atlas_size);
return PolychromeSpriteVertexOutput{device_position, tile_position,
sprite_id};
@ -188,8 +189,10 @@ fragment float4 polychrome_sprite_fragment(
min_filter::linear);
float4 sample =
atlas_texture.sample(atlas_texture_sampler, input.tile_position);
float clip_distance = quad_sdf(input.position.xy, sprite.content_mask.bounds,
sprite.content_mask.corner_radii);
float quad_distance = quad_sdf(input.position.xy, sprite.bounds, sprite.corner_radii);
float clip_distance = quad_sdf(input.position.xy, sprite.content_mask.bounds, Corners_ScaledPixels { 0., 0., 0., 0. });
float distance = max(quad_distance, clip_distance);
float4 color = sample;
if (sprite.grayscale) {
float grayscale = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
@ -197,7 +200,7 @@ fragment float4 polychrome_sprite_fragment(
color.g = grayscale;
color.b = grayscale;
}
color.a *= saturate(0.5 - clip_distance);
color.a *= saturate(0.5 - distance);
return color;
}

View file

@ -275,6 +275,7 @@ pub struct PolychromeSprite {
pub order: u32,
pub bounds: Bounds<ScaledPixels>,
pub content_mask: ScaledContentMask,
pub corner_radii: Corners<ScaledPixels>,
pub tile: AtlasTile,
pub grayscale: bool,
}

View file

@ -202,7 +202,6 @@ impl Style {
let min = current_mask.bounds.origin;
let max = current_mask.bounds.lower_right();
let mut mask_corner_radii = Corners::default();
let mask_bounds = match (
self.overflow.x == Overflow::Visible,
self.overflow.y == Overflow::Visible,
@ -220,14 +219,10 @@ impl Style {
point(bounds.lower_right().x, max.y),
),
// both hidden
(false, false) => {
mask_corner_radii = self.corner_radii.to_pixels(bounds, cx.rem_size());
bounds
}
(false, false) => bounds,
};
let mask = ContentMask {
bounds: mask_bounds,
corner_radii: mask_corner_radii,
};
cx.with_content_mask(mask, f)

View file

@ -76,24 +76,18 @@ impl Window {
#[derive(Clone, Debug)]
pub struct ContentMask {
pub bounds: Bounds<Pixels>,
pub corner_radii: Corners<Pixels>,
}
impl ContentMask {
pub fn scale(&self, factor: f32) -> ScaledContentMask {
ScaledContentMask {
bounds: self.bounds.scale(factor),
corner_radii: self.corner_radii.scale(factor),
}
}
pub fn intersect(&self, other: &Self) -> Self {
let bounds = self.bounds.intersect(&other.bounds);
// todo!("intersect corner radii")
ContentMask {
bounds,
corner_radii: self.corner_radii,
}
ContentMask { bounds }
}
}
@ -101,7 +95,6 @@ impl ContentMask {
#[repr(C)]
pub struct ScaledContentMask {
bounds: Bounds<ScaledPixels>,
corner_radii: Corners<ScaledPixels>,
}
pub struct WindowContext<'a, 'w> {
@ -202,23 +195,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
result
}
pub fn clip<F, R>(
&mut self,
bounds: Bounds<Pixels>,
corner_radii: Corners<Pixels>,
f: impl FnOnce(&mut Self) -> R,
) -> R {
let clip_mask = ContentMask {
bounds,
corner_radii,
};
self.window.content_mask_stack.push(clip_mask);
let result = f(self);
self.window.content_mask_stack.pop();
result
}
pub fn current_layer_id(&self) -> LayerId {
self.window.current_layer_id.clone()
}
@ -318,6 +294,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
PolychromeSprite {
order,
bounds,
corner_radii: Default::default(),
content_mask,
tile,
grayscale: false,
@ -371,6 +348,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
pub fn paint_image(
&mut self,
bounds: Bounds<Pixels>,
corner_radii: Corners<Pixels>,
order: u32,
data: Arc<ImageData>,
grayscale: bool,
@ -387,6 +365,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
Ok((data.size(), Cow::Borrowed(data.as_bytes())))
})?;
let content_mask = self.content_mask().scale(scale_factor);
let corner_radii = corner_radii.scale(scale_factor);
self.window.scene.insert(
layer_id,
@ -394,6 +373,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
order,
bounds,
content_mask,
corner_radii,
tile,
grayscale,
},
@ -505,7 +485,6 @@ pub trait BorrowWindow: BorrowAppContext {
origin: Point::default(),
size: self.window().content_size,
},
corner_radii: Default::default(),
})
}