Checkpoint

Antonio Scandurra created

Change summary

crates/gpui3/src/elements/img.rs | 20 ++++++++++++++++----
crates/gpui3/src/geometry.rs     | 22 ++++++++++++++++------
crates/gpui3/src/style.rs        |  7 +++++--
3 files changed, 37 insertions(+), 12 deletions(-)

Detailed changes

crates/gpui3/src/elements/img.rs 🔗

@@ -1,5 +1,6 @@
 use crate::{
-    Element, Layout, LayoutId, Result, SharedString, Style, StyleHelpers, Styled, ViewContext,
+    BorrowWindow, ContentMask, Element, IsZero, Layout, LayoutId, Result, SharedString, Style,
+    StyleHelpers, Styled, ViewContext,
 };
 use futures::FutureExt;
 use refineable::RefinementCascade;
@@ -64,14 +65,25 @@ impl<S: 'static> Element for Img<S> {
 
         style.paint(order, bounds, cx);
 
-        if let Some(uri) = &self.uri {
-            let image_future = cx.image_cache.get(uri.clone());
+        if let Some(uri) = self.uri.clone() {
+            let image_future = cx.image_cache.get(uri);
             if let Some(data) = image_future
                 .clone()
                 .now_or_never()
                 .and_then(ResultExt::log_err)
             {
-                cx.paint_image(bounds, order, data, self.grayscale)?;
+                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),
+                    )?;
+                }
             } else {
                 log::warn!("image not loaded yet");
                 // cx.spawn(|this, mut cx| async move {

crates/gpui3/src/geometry.rs 🔗

@@ -433,12 +433,13 @@ pub struct Corners<T: Clone + Debug> {
 }
 
 impl Corners<AbsoluteLength> {
-    pub fn to_pixels(&self, rem_size: Pixels) -> Corners<Pixels> {
+    pub fn to_pixels(&self, bounds: Bounds<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
+        let max = bounds.size.width.max(bounds.size.height) / 2.;
         Corners {
-            top_left: self.top_left.to_pixels(rem_size),
-            top_right: self.top_right.to_pixels(rem_size),
-            bottom_right: self.bottom_right.to_pixels(rem_size),
-            bottom_left: self.bottom_left.to_pixels(rem_size),
+            top_left: self.top_left.to_pixels(rem_size).min(max),
+            top_right: self.top_right.to_pixels(rem_size).min(max),
+            bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
+            bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
         }
     }
 }
@@ -925,6 +926,15 @@ impl<T: IsZero + Debug + Clone> IsZero for Size<T> {
 
 impl<T: IsZero + Debug + Clone> IsZero for Bounds<T> {
     fn is_zero(&self) -> bool {
-        self.origin.is_zero() && self.size.is_zero()
+        self.size.is_zero()
+    }
+}
+
+impl<T: IsZero + Debug + Clone> IsZero for Corners<T> {
+    fn is_zero(&self) -> bool {
+        self.top_left.is_zero()
+            && self.top_right.is_zero()
+            && self.bottom_right.is_zero()
+            && self.bottom_left.is_zero()
     }
 }

crates/gpui3/src/style.rs 🔗

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