Checkpoint

Nathan Sobo created

Change summary

crates/gpui3/src/geometry.rs    | 52 +++++++++++++++++++++++-----------
crates/gpui3/src/text_system.rs | 20 ++++++++++--
2 files changed, 51 insertions(+), 21 deletions(-)

Detailed changes

crates/gpui3/src/geometry.rs 🔗

@@ -29,13 +29,17 @@ impl<T: Clone + Debug> Point<T> {
     }
 }
 
-impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> Mul<S> for Point<T> {
-    type Output = Self;
+impl<T, Rhs> Mul<Rhs> for Point<T>
+where
+    T: Mul<Rhs, Output = Rhs> + Clone + Debug,
+    Rhs: Clone + Debug,
+{
+    type Output = Point<Rhs>;
 
-    fn mul(self, rhs: S) -> Self::Output {
-        Self {
-            x: self.x.clone() * rhs.clone(),
-            y: self.y.clone() * rhs,
+    fn mul(self, rhs: Rhs) -> Self::Output {
+        Point {
+            x: self.x * rhs.clone(),
+            y: self.y * rhs,
         }
     }
 }
@@ -125,13 +129,17 @@ impl<T: Clone + Debug> Size<T> {
     }
 }
 
-impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> Mul<S> for Size<T> {
-    type Output = Self;
+impl<T, Rhs> Mul<Rhs> for Size<T>
+where
+    T: Mul<Rhs, Output = Rhs> + Debug + Clone,
+    Rhs: Debug + Clone,
+{
+    type Output = Size<Rhs>;
 
-    fn mul(self, rhs: S) -> Self::Output {
-        Self {
-            width: self.width.clone() * rhs.clone(),
-            height: self.height.clone() * rhs,
+    fn mul(self, rhs: Rhs) -> Self::Output {
+        Size {
+            width: self.width * rhs.clone(),
+            height: self.height * rhs,
         }
     }
 }
@@ -190,14 +198,16 @@ pub struct Bounds<T: Clone + Debug> {
 unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Bounds<T> {}
 unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Bounds<T> {}
 
-impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> Mul<S> for Bounds<T>
+// Bounds<f32> * Pixels = Bounds<Pixels>
+impl<T, Rhs> Mul<Rhs> for Bounds<T>
 where
-    T: Mul<S, Output = T>,
+    T: Mul<Rhs, Output = Rhs> + Clone + Debug,
+    Rhs: Clone + Debug,
 {
-    type Output = Self;
+    type Output = Bounds<Rhs>;
 
-    fn mul(self, rhs: S) -> Self::Output {
-        Self {
+    fn mul(self, rhs: Rhs) -> Self::Output {
+        Bounds {
             origin: self.origin * rhs.clone(),
             size: self.size * rhs,
         }
@@ -404,6 +414,14 @@ impl Mul<f32> for Pixels {
     }
 }
 
+impl Mul<Pixels> for f32 {
+    type Output = Pixels;
+
+    fn mul(self, rhs: Pixels) -> Self::Output {
+        Pixels(self * rhs.0)
+    }
+}
+
 impl Pixels {
     pub fn round(&self) -> Self {
         Self(self.0.round())

crates/gpui3/src/text_system.rs 🔗

@@ -8,7 +8,7 @@ use line_wrapper::*;
 pub use text_layout_cache::*;
 
 use crate::{
-    px, Bounds, Hsla, Pixels, PlatformTextSystem, Point, Result, SharedString, UnderlineStyle,
+    px, Bounds, Hsla, Pixels, PlatformTextSystem, Point, Result, SharedString, Size, UnderlineStyle,
 };
 use collections::HashMap;
 use core::fmt;
@@ -90,9 +90,21 @@ impl TextSystem {
         })
     }
 
-    pub fn em_advance(&self, font_id: FontId, font_size: Pixels) -> Pixels {
-        todo!()
-        // self.font_cache.em_advance(font_id, font_size)
+    pub fn advance(&self, font: &Font, font_size: Pixels, ch: char) -> Result<Size<Pixels>> {
+        let font_id = self.font_id(font)?;
+        let glyph_id = self
+            .platform_text_system
+            .glyph_for_char(font_id, ch)
+            .ok_or_else(|| anyhow!("glyph not found for character '{}'", ch))?;
+        let result =
+            self.platform_text_system.advance(font_id, glyph_id)? / self.units_per_em(font)? as f32;
+
+        let result = result * font_size;
+        Ok(todo!())
+    }
+
+    pub fn units_per_em(&self, font: &Font) -> Result<u32> {
+        self.read_metrics(font, |metrics| metrics.units_per_em as u32)
     }
 
     pub fn line_height(&self, font_size: Pixels) -> Pixels {