diff --git a/crates/gpui3/src/geometry.rs b/crates/gpui3/src/geometry.rs index 7cffe4b59bac1881954ce359424efc3b4bfea730..5f92c927bdeca0e57824a84c8c06532f140033bb 100644 --- a/crates/gpui3/src/geometry.rs +++ b/crates/gpui3/src/geometry.rs @@ -478,6 +478,10 @@ impl Pixels { Self(self.0.round()) } + pub fn floor(&self) -> Self { + Self(self.0.floor()) + } + pub fn to_device_pixels(&self, scale: f32) -> DevicePixels { DevicePixels((self.0 * scale).ceil() as u32) } diff --git a/crates/gpui3/src/scene.rs b/crates/gpui3/src/scene.rs index f3e26f01973046d24a4c067ed42d4229f7f00dfb..00882097916b096b3b9210f715cd01d8da9873d7 100644 --- a/crates/gpui3/src/scene.rs +++ b/crates/gpui3/src/scene.rs @@ -10,7 +10,7 @@ pub type StackingOrder = SmallVec<[u32; 16]>; #[derive(Debug)] pub struct Scene { - scale_factor: f32, + pub(crate) scale_factor: f32, pub(crate) layers: BTreeMap, } @@ -29,8 +29,8 @@ impl Scene { } } - pub fn insert(&mut self, order: StackingOrder, primitive: impl Into) { - let layer = self.layers.entry(order).or_default(); + pub fn insert(&mut self, stacking_order: StackingOrder, primitive: impl Into) { + let layer = self.layers.entry(stacking_order).or_default(); let primitive = primitive.into(); match primitive { diff --git a/crates/gpui3/src/text_system/line.rs b/crates/gpui3/src/text_system/line.rs index 71ec13461f6d72966aea4b57f23c2b9e0b4d00c5..98b0abcdbd774e51c1c0a3ea23360a55eca594e6 100644 --- a/crates/gpui3/src/text_system/line.rs +++ b/crates/gpui3/src/text_system/line.rs @@ -1,10 +1,12 @@ use crate::{ - black, point, px, Bounds, FontId, Hsla, Layout, Pixels, Point, RasterizedGlyphId, RunStyle, - ShapedBoundary, ShapedLine, ShapedRun, UnderlineStyle, WindowContext, + black, point, px, Bounds, FontId, Hsla, Layout, MonochromeSprite, Pixels, Point, + RasterizedGlyphId, RunStyle, ShapedBoundary, ShapedLine, ShapedRun, UnderlineStyle, + WindowContext, }; use anyhow::Result; use smallvec::SmallVec; use std::sync::Arc; +use util::ResultExt; #[derive(Default, Debug, Clone)] pub struct Line { @@ -174,7 +176,28 @@ impl Line { // origin: glyph_origin, // }); } else { - todo!() + if let Some((tile, bounds)) = cx + .rasterize_glyph( + run.font_id, + glyph.id, + self.layout.font_size, + cx.scale_factor(), + glyph_origin, + ) + .log_err() + { + let layer_id = cx.current_layer_id(); + cx.scene().insert( + layer_id, + MonochromeSprite { + order: layout.order, + bounds, + color, + tile, + }, + ); + } + // cx.scene().insert(Symbol { // order: layout.order, // origin, diff --git a/crates/gpui3/src/window.rs b/crates/gpui3/src/window.rs index 97351e7869b617180e1ecb37b96a11e714826259..de518fb93fe25876bedac379e9fa37a7e0b70011 100644 --- a/crates/gpui3/src/window.rs +++ b/crates/gpui3/src/window.rs @@ -22,7 +22,7 @@ pub struct Window { layout_engine: TaffyLayoutEngine, pub(crate) root_view: Option>, mouse_position: Point, - current_stacking_order: StackingOrder, + current_layer_id: StackingOrder, pub(crate) scene: Scene, pub(crate) dirty: bool, } @@ -63,7 +63,7 @@ impl Window { layout_engine: TaffyLayoutEngine::new(), root_view: None, mouse_position, - current_stacking_order: SmallVec::new(), + current_layer_id: SmallVec::new(), scene: Scene::new(scale_factor), dirty: true, } @@ -122,6 +122,10 @@ impl<'a, 'w> WindowContext<'a, 'w> { .map(Into::into)?) } + pub fn scale_factor(&self) -> f32 { + self.window.scene.scale_factor + } + pub fn rem_size(&self) -> Pixels { self.window.rem_size } @@ -135,14 +139,14 @@ impl<'a, 'w> WindowContext<'a, 'w> { } pub fn stack(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R { - self.window.current_stacking_order.push(order); + self.window.current_layer_id.push(order); let result = f(self); - self.window.current_stacking_order.pop(); + self.window.current_layer_id.pop(); result } - pub fn current_stack_order(&self) -> StackingOrder { - self.window.current_stacking_order.clone() + pub fn current_layer_id(&self) -> StackingOrder { + self.window.current_layer_id.clone() } pub fn run_on_main( @@ -169,7 +173,7 @@ impl<'a, 'w> WindowContext<'a, 'w> { font_size: Pixels, scale_factor: f32, target_position: Point, - ) -> Result<(AtlasTile, Point)> { + ) -> Result<(AtlasTile, Bounds)> { let target_position = target_position * scale_factor; let subpixel_variant = Point { x: (target_position.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8, @@ -192,7 +196,14 @@ impl<'a, 'w> WindowContext<'a, 'w> { Ok((bounds.size, pixels)) })?; - Ok((tile, offset)) + // Align bounding box surrounding glyph to pixel grid + let mut origin = (target_position * scale_factor).map(|p| p.floor()); + // Position glyph within bounding box + origin += offset.map(|o| px(u32::from(o) as f32)); + let size = tile.bounds_in_atlas.size.map(|b| px(b.0 as f32)); + let bounds = Bounds { origin, size }; + + Ok((tile, bounds)) } pub(crate) fn draw(&mut self) -> Result<()> {