init

Junkui Zhang created

Change summary

crates/gpui/src/platform/windows/direct_write.rs | 62 +++++++++++------
1 file changed, 39 insertions(+), 23 deletions(-)

Detailed changes

crates/gpui/src/platform/windows/direct_write.rs 🔗

@@ -728,6 +728,7 @@ impl DirectWriteState {
     fn create_glyph_run_analysis(
         &self,
         params: &RenderGlyphParams,
+        scale: f32,
     ) -> Result<IDWriteGlyphRunAnalysis> {
         let font = &self.fonts[params.font_id.0];
         let glyph_id = [params.glyph_id.0 as u16];
@@ -744,18 +745,18 @@ impl DirectWriteState {
             bidiLevel: 0,
         };
         let transform = DWRITE_MATRIX {
-            m11: params.scale_factor,
+            m11: params.scale_factor * scale,
             m12: 0.0,
             m21: 0.0,
-            m22: params.scale_factor,
+            m22: params.scale_factor * scale,
             dx: 0.0,
             dy: 0.0,
         };
         let subpixel_shift = params
             .subpixel_variant
             .map(|v| v as f32 / SUBPIXEL_VARIANTS as f32);
-        let baseline_origin_x = subpixel_shift.x / params.scale_factor;
-        let baseline_origin_y = subpixel_shift.y / params.scale_factor;
+        let baseline_origin_x = subpixel_shift.x * scale / params.scale_factor;
+        let baseline_origin_y = subpixel_shift.y * scale / params.scale_factor;
 
         let mut rendering_mode = DWRITE_RENDERING_MODE1::default();
         let mut grid_fit_mode = DWRITE_GRID_FIT_MODE::default();
@@ -783,7 +784,8 @@ impl DirectWriteState {
                 DWRITE_MEASURING_MODE_NATURAL,
                 grid_fit_mode,
                 // We're using cleartype not grayscale for monochrome is because it provides better quality
-                DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE,
+                // DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE,
+                DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE,
                 baseline_origin_x,
                 baseline_origin_y,
             )
@@ -792,7 +794,7 @@ impl DirectWriteState {
     }
 
     fn raster_bounds(&self, params: &RenderGlyphParams) -> Result<Bounds<DevicePixels>> {
-        let glyph_analysis = self.create_glyph_run_analysis(params)?;
+        let glyph_analysis = self.create_glyph_run_analysis(params, 1.0)?;
 
         let bounds = unsafe { glyph_analysis.GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1)? };
         // Some glyphs cannot be drawn with ClearType, such as bitmap fonts. In that case
@@ -817,10 +819,13 @@ impl DirectWriteState {
                 })
             } else {
                 Ok(Bounds {
-                    origin: point((bounds.left as i32).into(), (bounds.top as i32).into()),
+                    origin: point(
+                        (bounds.left as i32 - 1).into(),
+                        (bounds.top as i32 - 1).into(),
+                    ),
                     size: size(
-                        (bounds.right - bounds.left).into(),
-                        (bounds.bottom - bounds.top).into(),
+                        (bounds.right - bounds.left + 2).into(),
+                        (bounds.bottom - bounds.top + 2).into(),
                     ),
                 })
             }
@@ -872,18 +877,19 @@ impl DirectWriteState {
         glyph_bounds: Bounds<DevicePixels>,
     ) -> Result<Vec<u8>> {
         let mut bitmap_data =
-            vec![0u8; glyph_bounds.size.width.0 as usize * glyph_bounds.size.height.0 as usize * 3];
+            vec![0u8; glyph_bounds.size.width.0 as usize * glyph_bounds.size.height.0 as usize * 4];
 
-        let glyph_analysis = self.create_glyph_run_analysis(params)?;
+        let glyph_analysis = self.create_glyph_run_analysis(params, 2.0)?;
         unsafe {
             glyph_analysis.CreateAlphaTexture(
                 // We're using cleartype not grayscale for monochrome is because it provides better quality
-                DWRITE_TEXTURE_CLEARTYPE_3x1,
+                // DWRITE_TEXTURE_CLEARTYPE_3x1,
+                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,
+                    left: glyph_bounds.origin.x.0 * 2,
+                    top: glyph_bounds.origin.y.0 * 2,
+                    right: glyph_bounds.size.width.0 * 2 + glyph_bounds.origin.x.0 * 2,
+                    bottom: glyph_bounds.size.height.0 * 2 + glyph_bounds.origin.y.0 * 2,
                 },
                 &mut bitmap_data,
             )?;
@@ -892,21 +898,31 @@ impl DirectWriteState {
         let bitmap_factory = self.components.bitmap_factory.resolve()?;
         let bitmap = unsafe {
             bitmap_factory.CreateBitmapFromMemory(
-                glyph_bounds.size.width.0 as u32,
-                glyph_bounds.size.height.0 as u32,
-                &GUID_WICPixelFormat24bppRGB,
-                glyph_bounds.size.width.0 as u32 * 3,
+                glyph_bounds.size.width.0 as u32 * 2,
+                glyph_bounds.size.height.0 as u32 * 2,
+                // &GUID_WICPixelFormat24bppRGB,
+                &GUID_WICPixelFormat8bppGray,
+                glyph_bounds.size.width.0 as u32 * 2,
                 &bitmap_data,
             )
         }?;
 
-        let grayscale_bitmap =
-            unsafe { WICConvertBitmapSource(&GUID_WICPixelFormat8bppGray, &bitmap) }?;
+        // let grayscale_bitmap =
+        //     unsafe { WICConvertBitmapSource(&GUID_WICPixelFormat8bppGray, &bitmap) }?;
+        let scaler = unsafe { bitmap_factory.CreateBitmapScaler()? };
+        unsafe {
+            scaler.Initialize(
+                &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 {
-            grayscale_bitmap.CopyPixels(
+            scaler.CopyPixels(
                 std::ptr::null() as _,
                 glyph_bounds.size.width.0 as u32,
                 &mut bitmap_data,