From 5f3dbb05d64aed486b1e672b72f281a1560329f3 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 24 Mar 2021 18:35:48 +0100 Subject: [PATCH] Honor vertical subpixel positions Co-Authored-By: Nathan Sobo --- gpui/src/platform/mac/fonts.rs | 14 ++++++------- gpui/src/platform/mac/renderer.rs | 2 +- gpui/src/platform/mac/sprite_cache.rs | 29 ++++++++++++++++++--------- gpui/src/platform/mod.rs | 2 +- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/gpui/src/platform/mac/fonts.rs b/gpui/src/platform/mac/fonts.rs index 67041e012a..f1b94e5ef4 100644 --- a/gpui/src/platform/mac/fonts.rs +++ b/gpui/src/platform/mac/fonts.rs @@ -3,7 +3,7 @@ use crate::{ geometry::{ rect::{RectF, RectI}, transform2d::Transform2F, - vector::{vec2f, vec2i}, + vector::{vec2f, vec2i, Vector2F}, }, platform, text_layout::{Glyph, Line, Run}, @@ -71,12 +71,12 @@ impl platform::FontSystem for FontSystem { font_id: FontId, font_size: f32, glyph_id: GlyphId, - horizontal_shift: f32, + subpixel_shift: Vector2F, scale_factor: f32, ) -> Option<(RectI, Vec)> { self.0 .read() - .rasterize_glyph(font_id, font_size, glyph_id, horizontal_shift, scale_factor) + .rasterize_glyph(font_id, font_size, glyph_id, subpixel_shift, scale_factor) } fn layout_str( @@ -126,7 +126,7 @@ impl FontSystemState { font_id: FontId, font_size: f32, glyph_id: GlyphId, - horizontal_shift: f32, + subpixel_shift: Vector2F, scale_factor: f32, ) -> Option<(RectI, Vec)> { let font = &self.fonts[font_id.0]; @@ -145,7 +145,7 @@ impl FontSystemState { None } else { // Make room for subpixel variants. - let bounds = RectI::new(bounds.origin(), bounds.size() + vec2i(1, 0)); + let bounds = RectI::new(bounds.origin(), bounds.size() + vec2i(1, 1)); let mut pixels = vec![0; bounds.width() as usize * bounds.height() as usize]; let ctx = CGContext::create_bitmap_context( Some(pixels.as_mut_ptr() as *mut _), @@ -175,8 +175,8 @@ impl FontSystemState { ctx.show_glyphs_at_positions( &[glyph_id as CGGlyph], &[CGPoint::new( - (horizontal_shift / scale_factor) as CGFloat, - 0.0, + (subpixel_shift.x() / scale_factor) as CGFloat, + (subpixel_shift.y() / scale_factor) as CGFloat, )], ); diff --git a/gpui/src/platform/mac/renderer.rs b/gpui/src/platform/mac/renderer.rs index 2710389c1c..ba727c9bd1 100644 --- a/gpui/src/platform/mac/renderer.rs +++ b/gpui/src/platform/mac/renderer.rs @@ -272,7 +272,7 @@ impl Renderer { glyph.font_id, glyph.font_size, glyph.id, - glyph.origin.x(), + glyph.origin, scene.scale_factor(), ) { sprites_by_atlas diff --git a/gpui/src/platform/mac/sprite_cache.rs b/gpui/src/platform/mac/sprite_cache.rs index c48c4577de..70012212a6 100644 --- a/gpui/src/platform/mac/sprite_cache.rs +++ b/gpui/src/platform/mac/sprite_cache.rs @@ -2,7 +2,7 @@ use crate::{ fonts::{FontId, GlyphId}, geometry::{ rect::RectI, - vector::{vec2i, Vector2F, Vector2I}, + vector::{vec2f, vec2i, Vector2F, Vector2I}, }, platform, }; @@ -16,7 +16,7 @@ struct GlyphDescriptor { font_id: FontId, font_size: OrderedFloat, glyph_id: GlyphId, - subpixel_variant: u8, + subpixel_variant: (u8, u8), } #[derive(Clone)] @@ -60,18 +60,22 @@ impl SpriteCache { font_id: FontId, font_size: f32, glyph_id: GlyphId, - target_x: f32, + target_position: Vector2F, scale_factor: f32, ) -> Option { const SUBPIXEL_VARIANTS: u8 = 4; - let target_x = target_x * scale_factor; + let target_position = target_position * scale_factor; let fonts = &self.fonts; let atlasses = &mut self.atlasses; let atlas_size = self.atlas_size; let device = &self.device; - let subpixel_variant = - (target_x.fract() * SUBPIXEL_VARIANTS as f32).round() as u8 % SUBPIXEL_VARIANTS; + let subpixel_variant = ( + (target_position.x().fract() * SUBPIXEL_VARIANTS as f32).round() as u8 + % SUBPIXEL_VARIANTS, + (target_position.y().fract() * SUBPIXEL_VARIANTS as f32).round() as u8 + % SUBPIXEL_VARIANTS, + ); self.glyphs .entry(GlyphDescriptor { font_id, @@ -80,12 +84,15 @@ impl SpriteCache { subpixel_variant, }) .or_insert_with(|| { - let horizontal_shift = subpixel_variant as f32 / SUBPIXEL_VARIANTS as f32; + let subpixel_shift = vec2f( + subpixel_variant.0 as f32 / SUBPIXEL_VARIANTS as f32, + subpixel_variant.1 as f32 / SUBPIXEL_VARIANTS as f32, + ); let (glyph_bounds, mask) = fonts.rasterize_glyph( font_id, font_size, glyph_id, - horizontal_shift, + subpixel_shift, scale_factor, )?; assert!(glyph_bounds.width() < atlas_size.x()); @@ -102,8 +109,10 @@ impl SpriteCache { bounds }); - let mut offset = glyph_bounds.origin().to_f32(); - offset.set_x(offset.x() - target_x.fract()); + // Snap sprite to pixel grid. + let offset = glyph_bounds.origin().to_f32() + - vec2f(target_position.x().fract(), target_position.y().fract()); + Some(GlyphSprite { atlas_id: atlasses.len() - 1, atlas_origin: atlas_bounds.origin(), diff --git a/gpui/src/platform/mod.rs b/gpui/src/platform/mod.rs index c329bb4651..61a8ab5874 100644 --- a/gpui/src/platform/mod.rs +++ b/gpui/src/platform/mod.rs @@ -78,7 +78,7 @@ pub trait FontSystem: Send + Sync { font_id: FontId, font_size: f32, glyph_id: GlyphId, - horizontal_shift: f32, + subpixel_shift: Vector2F, scale_factor: f32, ) -> Option<(RectI, Vec)>; fn layout_str(&self, text: &str, font_size: f32, runs: &[(Range, FontId)]) -> Line;