Checkpoint
This commit is contained in:
parent
133c3a330c
commit
5aa45607eb
5 changed files with 25 additions and 57 deletions
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
BorrowWindow, ContentMask, Element, IsZero, Layout, LayoutId, Result, SharedString, Style,
|
BorrowWindow, Element, Layout, LayoutId, Result, SharedString, Style, StyleHelpers, Styled,
|
||||||
StyleHelpers, Styled, ViewContext,
|
ViewContext,
|
||||||
};
|
};
|
||||||
use futures::FutureExt;
|
use futures::FutureExt;
|
||||||
use refineable::RefinementCascade;
|
use refineable::RefinementCascade;
|
||||||
|
@ -73,17 +73,7 @@ impl<S: 'static> Element for Img<S> {
|
||||||
.and_then(ResultExt::log_err)
|
.and_then(ResultExt::log_err)
|
||||||
{
|
{
|
||||||
let corner_radii = style.corner_radii.to_pixels(bounds, cx.rem_size());
|
let corner_radii = style.corner_radii.to_pixels(bounds, cx.rem_size());
|
||||||
if corner_radii.is_zero() {
|
cx.paint_image(bounds, corner_radii, order, data, self.grayscale)?;
|
||||||
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),
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
log::warn!("image not loaded yet");
|
log::warn!("image not loaded yet");
|
||||||
// cx.spawn(|this, mut cx| async move {
|
// cx.spawn(|this, mut cx| async move {
|
||||||
|
|
|
@ -106,11 +106,7 @@ fragment float4 quad_fragment(QuadVertexOutput input [[stage_in]],
|
||||||
color = float4(premultiplied_output_rgb, output_alpha);
|
color = float4(premultiplied_output_rgb, output_alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
float clip_distance =
|
return color * float4(1., 1., 1., saturate(0.5 - 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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MonochromeSpriteVertexOutput {
|
struct MonochromeSpriteVertexOutput {
|
||||||
|
@ -131,8 +127,9 @@ vertex MonochromeSpriteVertexOutput monochrome_sprite_vertex(
|
||||||
|
|
||||||
float2 unit_vertex = unit_vertices[unit_vertex_id];
|
float2 unit_vertex = unit_vertices[unit_vertex_id];
|
||||||
MonochromeSprite sprite = sprites[sprite_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(
|
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);
|
float2 tile_position = to_tile_position(unit_vertex, sprite.tile, atlas_size);
|
||||||
float4 color = hsla_to_rgba(sprite.color);
|
float4 color = hsla_to_rgba(sprite.color);
|
||||||
return MonochromeSpriteVertexOutput{device_position, tile_position, color,
|
return MonochromeSpriteVertexOutput{device_position, tile_position, color,
|
||||||
|
@ -148,8 +145,11 @@ fragment float4 monochrome_sprite_fragment(
|
||||||
min_filter::linear);
|
min_filter::linear);
|
||||||
float4 sample =
|
float4 sample =
|
||||||
atlas_texture.sample(atlas_texture_sampler, input.tile_position);
|
atlas_texture.sample(atlas_texture_sampler, input.tile_position);
|
||||||
float clip_distance = quad_sdf(input.position.xy, sprite.content_mask.bounds,
|
float clip_distance = quad_sdf(
|
||||||
sprite.content_mask.corner_radii);
|
input.position.xy,
|
||||||
|
sprite.content_mask.bounds,
|
||||||
|
Corners_ScaledPixels { 0., 0., 0., 0. }
|
||||||
|
);
|
||||||
float4 color = input.color;
|
float4 color = input.color;
|
||||||
color.a *= sample.a * saturate(0.5 - clip_distance);
|
color.a *= sample.a * saturate(0.5 - clip_distance);
|
||||||
return color;
|
return color;
|
||||||
|
@ -172,8 +172,9 @@ vertex PolychromeSpriteVertexOutput polychrome_sprite_vertex(
|
||||||
|
|
||||||
float2 unit_vertex = unit_vertices[unit_vertex_id];
|
float2 unit_vertex = unit_vertices[unit_vertex_id];
|
||||||
PolychromeSprite sprite = sprites[sprite_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(
|
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);
|
float2 tile_position = to_tile_position(unit_vertex, sprite.tile, atlas_size);
|
||||||
return PolychromeSpriteVertexOutput{device_position, tile_position,
|
return PolychromeSpriteVertexOutput{device_position, tile_position,
|
||||||
sprite_id};
|
sprite_id};
|
||||||
|
@ -188,8 +189,10 @@ fragment float4 polychrome_sprite_fragment(
|
||||||
min_filter::linear);
|
min_filter::linear);
|
||||||
float4 sample =
|
float4 sample =
|
||||||
atlas_texture.sample(atlas_texture_sampler, input.tile_position);
|
atlas_texture.sample(atlas_texture_sampler, input.tile_position);
|
||||||
float clip_distance = quad_sdf(input.position.xy, sprite.content_mask.bounds,
|
float quad_distance = quad_sdf(input.position.xy, sprite.bounds, sprite.corner_radii);
|
||||||
sprite.content_mask.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;
|
float4 color = sample;
|
||||||
if (sprite.grayscale) {
|
if (sprite.grayscale) {
|
||||||
float grayscale = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
|
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.g = grayscale;
|
||||||
color.b = grayscale;
|
color.b = grayscale;
|
||||||
}
|
}
|
||||||
color.a *= saturate(0.5 - clip_distance);
|
color.a *= saturate(0.5 - distance);
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -275,6 +275,7 @@ pub struct PolychromeSprite {
|
||||||
pub order: u32,
|
pub order: u32,
|
||||||
pub bounds: Bounds<ScaledPixels>,
|
pub bounds: Bounds<ScaledPixels>,
|
||||||
pub content_mask: ScaledContentMask,
|
pub content_mask: ScaledContentMask,
|
||||||
|
pub corner_radii: Corners<ScaledPixels>,
|
||||||
pub tile: AtlasTile,
|
pub tile: AtlasTile,
|
||||||
pub grayscale: bool,
|
pub grayscale: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,7 +202,6 @@ impl Style {
|
||||||
let min = current_mask.bounds.origin;
|
let min = current_mask.bounds.origin;
|
||||||
let max = current_mask.bounds.lower_right();
|
let max = current_mask.bounds.lower_right();
|
||||||
|
|
||||||
let mut mask_corner_radii = Corners::default();
|
|
||||||
let mask_bounds = match (
|
let mask_bounds = match (
|
||||||
self.overflow.x == Overflow::Visible,
|
self.overflow.x == Overflow::Visible,
|
||||||
self.overflow.y == Overflow::Visible,
|
self.overflow.y == Overflow::Visible,
|
||||||
|
@ -220,14 +219,10 @@ impl Style {
|
||||||
point(bounds.lower_right().x, max.y),
|
point(bounds.lower_right().x, max.y),
|
||||||
),
|
),
|
||||||
// both hidden
|
// both hidden
|
||||||
(false, false) => {
|
(false, false) => bounds,
|
||||||
mask_corner_radii = self.corner_radii.to_pixels(bounds, cx.rem_size());
|
|
||||||
bounds
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let mask = ContentMask {
|
let mask = ContentMask {
|
||||||
bounds: mask_bounds,
|
bounds: mask_bounds,
|
||||||
corner_radii: mask_corner_radii,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.with_content_mask(mask, f)
|
cx.with_content_mask(mask, f)
|
||||||
|
|
|
@ -76,24 +76,18 @@ impl Window {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ContentMask {
|
pub struct ContentMask {
|
||||||
pub bounds: Bounds<Pixels>,
|
pub bounds: Bounds<Pixels>,
|
||||||
pub corner_radii: Corners<Pixels>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContentMask {
|
impl ContentMask {
|
||||||
pub fn scale(&self, factor: f32) -> ScaledContentMask {
|
pub fn scale(&self, factor: f32) -> ScaledContentMask {
|
||||||
ScaledContentMask {
|
ScaledContentMask {
|
||||||
bounds: self.bounds.scale(factor),
|
bounds: self.bounds.scale(factor),
|
||||||
corner_radii: self.corner_radii.scale(factor),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intersect(&self, other: &Self) -> Self {
|
pub fn intersect(&self, other: &Self) -> Self {
|
||||||
let bounds = self.bounds.intersect(&other.bounds);
|
let bounds = self.bounds.intersect(&other.bounds);
|
||||||
// todo!("intersect corner radii")
|
ContentMask { bounds }
|
||||||
ContentMask {
|
|
||||||
bounds,
|
|
||||||
corner_radii: self.corner_radii,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +95,6 @@ impl ContentMask {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ScaledContentMask {
|
pub struct ScaledContentMask {
|
||||||
bounds: Bounds<ScaledPixels>,
|
bounds: Bounds<ScaledPixels>,
|
||||||
corner_radii: Corners<ScaledPixels>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WindowContext<'a, 'w> {
|
pub struct WindowContext<'a, 'w> {
|
||||||
|
@ -202,23 +195,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
||||||
result
|
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 {
|
pub fn current_layer_id(&self) -> LayerId {
|
||||||
self.window.current_layer_id.clone()
|
self.window.current_layer_id.clone()
|
||||||
}
|
}
|
||||||
|
@ -318,6 +294,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
||||||
PolychromeSprite {
|
PolychromeSprite {
|
||||||
order,
|
order,
|
||||||
bounds,
|
bounds,
|
||||||
|
corner_radii: Default::default(),
|
||||||
content_mask,
|
content_mask,
|
||||||
tile,
|
tile,
|
||||||
grayscale: false,
|
grayscale: false,
|
||||||
|
@ -371,6 +348,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
||||||
pub fn paint_image(
|
pub fn paint_image(
|
||||||
&mut self,
|
&mut self,
|
||||||
bounds: Bounds<Pixels>,
|
bounds: Bounds<Pixels>,
|
||||||
|
corner_radii: Corners<Pixels>,
|
||||||
order: u32,
|
order: u32,
|
||||||
data: Arc<ImageData>,
|
data: Arc<ImageData>,
|
||||||
grayscale: bool,
|
grayscale: bool,
|
||||||
|
@ -387,6 +365,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
||||||
Ok((data.size(), Cow::Borrowed(data.as_bytes())))
|
Ok((data.size(), Cow::Borrowed(data.as_bytes())))
|
||||||
})?;
|
})?;
|
||||||
let content_mask = self.content_mask().scale(scale_factor);
|
let content_mask = self.content_mask().scale(scale_factor);
|
||||||
|
let corner_radii = corner_radii.scale(scale_factor);
|
||||||
|
|
||||||
self.window.scene.insert(
|
self.window.scene.insert(
|
||||||
layer_id,
|
layer_id,
|
||||||
|
@ -394,6 +373,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
||||||
order,
|
order,
|
||||||
bounds,
|
bounds,
|
||||||
content_mask,
|
content_mask,
|
||||||
|
corner_radii,
|
||||||
tile,
|
tile,
|
||||||
grayscale,
|
grayscale,
|
||||||
},
|
},
|
||||||
|
@ -505,7 +485,6 @@ pub trait BorrowWindow: BorrowAppContext {
|
||||||
origin: Point::default(),
|
origin: Point::default(),
|
||||||
size: self.window().content_size,
|
size: self.window().content_size,
|
||||||
},
|
},
|
||||||
corner_radii: Default::default(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue