diff --git a/crates/gpui2/src/platform.rs b/crates/gpui2/src/platform.rs index 8b49addec9..00ce3340f8 100644 --- a/crates/gpui2/src/platform.rs +++ b/crates/gpui2/src/platform.rs @@ -184,7 +184,11 @@ pub trait PlatformTextSystem: Send + Sync { fn advance(&self, font_id: FontId, glyph_id: GlyphId) -> Result>; fn glyph_for_char(&self, font_id: FontId, ch: char) -> Option; fn glyph_raster_bounds(&self, params: &RenderGlyphParams) -> Result>; - fn rasterize_glyph(&self, params: &RenderGlyphParams) -> Result<(Size, Vec)>; + fn rasterize_glyph( + &self, + params: &RenderGlyphParams, + raster_bounds: Bounds, + ) -> Result<(Size, Vec)>; fn layout_line(&self, text: &str, font_size: Pixels, runs: &[FontRun]) -> LineLayout; fn wrap_line( &self, diff --git a/crates/gpui2/src/platform/mac/text_system.rs b/crates/gpui2/src/platform/mac/text_system.rs index b87db09dc0..155f3097fe 100644 --- a/crates/gpui2/src/platform/mac/text_system.rs +++ b/crates/gpui2/src/platform/mac/text_system.rs @@ -116,7 +116,9 @@ impl PlatformTextSystem for MacTextSystem { }, )?; - Ok(candidates[ix]) + let font_id = candidates[ix]; + lock.font_selections.insert(font.clone(), font_id); + Ok(font_id) } } @@ -145,8 +147,9 @@ impl PlatformTextSystem for MacTextSystem { fn rasterize_glyph( &self, glyph_id: &RenderGlyphParams, + raster_bounds: Bounds, ) -> Result<(Size, Vec)> { - self.0.read().rasterize_glyph(glyph_id) + self.0.read().rasterize_glyph(glyph_id, raster_bounds) } fn layout_line(&self, text: &str, font_size: Pixels, font_runs: &[FontRun]) -> LineLayout { @@ -247,8 +250,11 @@ impl MacTextSystemState { .into()) } - fn rasterize_glyph(&self, params: &RenderGlyphParams) -> Result<(Size, Vec)> { - let glyph_bounds = self.raster_bounds(params)?; + fn rasterize_glyph( + &self, + params: &RenderGlyphParams, + glyph_bounds: Bounds, + ) -> Result<(Size, Vec)> { if glyph_bounds.size.width.0 == 0 || glyph_bounds.size.height.0 == 0 { Err(anyhow!("glyph bounds are empty")) } else { @@ -260,6 +266,7 @@ impl MacTextSystemState { if params.subpixel_variant.y > 0 { bitmap_size.height += DevicePixels(1); } + let bitmap_size = bitmap_size; let mut bytes; let cx; diff --git a/crates/gpui2/src/text_system.rs b/crates/gpui2/src/text_system.rs index e8d6acc5a3..c7031fcb4d 100644 --- a/crates/gpui2/src/text_system.rs +++ b/crates/gpui2/src/text_system.rs @@ -39,6 +39,7 @@ pub struct TextSystem { platform_text_system: Arc, font_ids_by_font: RwLock>, font_metrics: RwLock>, + raster_bounds: RwLock>>, wrapper_pool: Mutex>>, font_runs_pool: Mutex>>, } @@ -48,10 +49,11 @@ impl TextSystem { TextSystem { line_layout_cache: Arc::new(LineLayoutCache::new(platform_text_system.clone())), platform_text_system, - font_metrics: RwLock::new(HashMap::default()), - font_ids_by_font: RwLock::new(HashMap::default()), - wrapper_pool: Mutex::new(HashMap::default()), - font_runs_pool: Default::default(), + font_metrics: RwLock::default(), + raster_bounds: RwLock::default(), + font_ids_by_font: RwLock::default(), + wrapper_pool: Mutex::default(), + font_runs_pool: Mutex::default(), } } @@ -252,14 +254,24 @@ impl TextSystem { } pub fn raster_bounds(&self, params: &RenderGlyphParams) -> Result> { - self.platform_text_system.glyph_raster_bounds(params) + let raster_bounds = self.raster_bounds.upgradable_read(); + if let Some(bounds) = raster_bounds.get(params) { + Ok(bounds.clone()) + } else { + let mut raster_bounds = RwLockUpgradableReadGuard::upgrade(raster_bounds); + let bounds = self.platform_text_system.glyph_raster_bounds(params)?; + raster_bounds.insert(params.clone(), bounds); + Ok(bounds) + } } pub fn rasterize_glyph( &self, - glyph_id: &RenderGlyphParams, + params: &RenderGlyphParams, ) -> Result<(Size, Vec)> { - self.platform_text_system.rasterize_glyph(glyph_id) + let raster_bounds = self.raster_bounds(params)?; + self.platform_text_system + .rasterize_glyph(params, raster_bounds) } }