diff --git a/crates/gpui/src/platform/windows/direct_write.rs b/crates/gpui/src/platform/windows/direct_write.rs index 009e43f522301787883b890453d904052481fb5d..8d92eb2189966efcedbd7f0531e5d31f98be55b7 100644 --- a/crates/gpui/src/platform/windows/direct_write.rs +++ b/crates/gpui/src/platform/windows/direct_write.rs @@ -778,7 +778,7 @@ impl DirectWriteState { let antialias_mode = if params.is_emoji { DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE } else { - DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE + DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE }; let glyph_analysis = unsafe { @@ -814,7 +814,7 @@ impl DirectWriteState { } } - let bounds = unsafe { glyph_analysis.GetAlphaTextureBounds(DWRITE_TEXTURE_ALIASED_1x1)? }; + let bounds = unsafe { glyph_analysis.GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1)? }; if bounds.right < bounds.left { Ok(Bounds { @@ -856,46 +856,84 @@ impl DirectWriteState { let bitmap_size = glyph_bounds.size; - let glyph_analysis = self.create_glyph_run_analysis(params)?; - let mut bitmap_data: Vec; if params.is_emoji { + let glyph_analysis = self.create_glyph_run_analysis(params)?; + if let Ok(color) = self.rasterize_color(¶ms, glyph_bounds) { bitmap_data = color; } else { - let monochrome = Self::rasterize_monochrome(&glyph_analysis, glyph_bounds)?; + let monochrome = self.rasterize_monochrome(&glyph_analysis, glyph_bounds)?; bitmap_data = monochrome .into_iter() .flat_map(|pixel| [0, 0, 0, pixel]) .collect::>(); } } else { - bitmap_data = Self::rasterize_monochrome(&glyph_analysis, glyph_bounds)?; + let glyph_analysis = self.create_glyph_run_analysis(params)?; + bitmap_data = self.rasterize_monochrome(&glyph_analysis, glyph_bounds)?; } Ok((bitmap_size, bitmap_data)) } fn rasterize_monochrome( + &self, glyph_analysis: &IDWriteGlyphRunAnalysis, glyph_bounds: Bounds, ) -> Result> { + let multisampled_bounds = + unsafe { glyph_analysis.GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1)? }; + let multisampled_size = size( + multisampled_bounds.right - multisampled_bounds.left, + multisampled_bounds.bottom - multisampled_bounds.top, + ); + let mut bitmap_data = - vec![0u8; glyph_bounds.size.width.0 as usize * glyph_bounds.size.height.0 as usize]; + vec![0u8; multisampled_size.width as usize * multisampled_size.height as usize * 3]; unsafe { glyph_analysis.CreateAlphaTexture( - DWRITE_TEXTURE_ALIASED_1x1, - &RECT { - left: glyph_bounds.origin.x.0, - top: glyph_bounds.origin.y.0, - right: glyph_bounds.size.width.0 + glyph_bounds.origin.x.0, - bottom: glyph_bounds.size.height.0 + glyph_bounds.origin.y.0, - }, + DWRITE_TEXTURE_CLEARTYPE_3x1, + &multisampled_bounds, &mut bitmap_data, )?; } + let bitmap_factory = self.components.bitmap_factory.resolve()?; + let bitmap = unsafe { + bitmap_factory.CreateBitmapFromMemory( + multisampled_size.width as u32, + multisampled_size.height as u32, + &GUID_WICPixelFormat24bppRGB, + multisampled_size.width as u32 * 3, + &bitmap_data, + ) + }?; + + let grayscale_bitmap = + unsafe { WICConvertBitmapSource(&GUID_WICPixelFormat8bppGray, &bitmap) }?; + + let scaler = unsafe { bitmap_factory.CreateBitmapScaler() }?; + unsafe { + scaler.Initialize( + &grayscale_bitmap, + glyph_bounds.size.width.0 as u32, + glyph_bounds.size.height.0 as u32, + WICBitmapInterpolationModeHighQualityCubic, + ) + }?; + + let mut bitmap_data = + vec![0u8; glyph_bounds.size.width.0 as usize * glyph_bounds.size.height.0 as usize]; + unsafe { + scaler.CopyPixels( + std::ptr::null() as _, + glyph_bounds.size.width.0 as u32, + &mut bitmap_data, + ) + }?; + Ok(bitmap_data) }