cosmic_text: Handle subpixel variants (#16238)

apricotbucket28 created

Closes https://github.com/zed-industries/zed/issues/14169, closes
https://github.com/zed-industries/zed/issues/14387


| Before  | After |
| --- | ---|
|
![image](https://github.com/user-attachments/assets/e7acbcbf-6384-49f8-bfe4-96d70d957df2)
|
![image](https://github.com/user-attachments/assets/704fac78-3946-4c5f-a02d-346653b77c5a)
|
|
![image](https://github.com/user-attachments/assets/50c40a23-47a8-4bc4-9a8c-df763df38f18)
|
![image](https://github.com/user-attachments/assets/37e5b1a6-0e16-4564-a47e-94f4e6d82c10)
|

Release Notes:

- Linux: Improved text rendering by handling subpixel positioning.

Change summary

crates/gpui/src/platform/linux/text_system.rs | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)

Detailed changes

crates/gpui/src/platform/linux/text_system.rs 🔗

@@ -1,7 +1,7 @@
 use crate::{
     point, size, Bounds, DevicePixels, Font, FontFeatures, FontId, FontMetrics, FontRun, FontStyle,
     FontWeight, GlyphId, LineLayout, Pixels, PlatformTextSystem, Point, RenderGlyphParams,
-    ShapedGlyph, SharedString, Size,
+    ShapedGlyph, SharedString, Size, SUBPIXEL_VARIANTS,
 };
 use anyhow::{anyhow, Context, Ok, Result};
 use collections::HashMap;
@@ -284,11 +284,10 @@ impl CosmicTextSystemState {
 
     fn raster_bounds(&mut self, params: &RenderGlyphParams) -> Result<Bounds<DevicePixels>> {
         let font = &self.loaded_fonts_store[params.font_id.0];
-        let font_system = &mut self.font_system;
         let image = self
             .swash_cache
             .get_image(
-                font_system,
+                &mut self.font_system,
                 CacheKey::new(
                     font.id(),
                     params.glyph_id.0 as u16,
@@ -315,19 +314,20 @@ impl CosmicTextSystemState {
         if glyph_bounds.size.width.0 == 0 || glyph_bounds.size.height.0 == 0 {
             Err(anyhow!("glyph bounds are empty"))
         } else {
-            // todo(linux) handle subpixel variants
             let bitmap_size = glyph_bounds.size;
             let font = &self.loaded_fonts_store[params.font_id.0];
-            let font_system = &mut self.font_system;
+            let subpixel_shift = params
+                .subpixel_variant
+                .map(|v| v as f32 / (SUBPIXEL_VARIANTS as f32 * params.scale_factor));
             let mut image = self
                 .swash_cache
                 .get_image(
-                    font_system,
+                    &mut self.font_system,
                     CacheKey::new(
                         font.id(),
                         params.glyph_id.0 as u16,
                         (params.font_size * params.scale_factor).into(),
-                        (0.0, 0.0),
+                        (subpixel_shift.x, subpixel_shift.y.trunc()),
                         cosmic_text::CacheKeyFlags::empty(),
                     )
                     .0,