From ed86b86dc7fb59454e4f27d45c9f79eccd1193bf Mon Sep 17 00:00:00 2001 From: apricotbucket28 <71973804+apricotbucket28@users.noreply.github.com> Date: Mon, 3 Jun 2024 13:25:44 -0300 Subject: [PATCH] cosmic_text: Handle variation selectors; fix emoji colors (#12587) Basically, we detect if a glyph is a variation selector if its `id` is 3 (i.e. a whitespace character) and if it comes from an emoji font (since variation selectors are only used for emoji glyphs). - Fixes https://github.com/zed-industries/zed/issues/11703 and https://github.com/zed-industries/zed/issues/12022 Release Notes: - N/A --- .../src/platform/cosmic_text/text_system.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/crates/gpui/src/platform/cosmic_text/text_system.rs b/crates/gpui/src/platform/cosmic_text/text_system.rs index c1c5f5aa8039b740cfd21f3deee434e393366418..57032dc6468bc190386f54b30c15d4f8c40f6fa4 100644 --- a/crates/gpui/src/platform/cosmic_text/text_system.rs +++ b/crates/gpui/src/platform/cosmic_text/text_system.rs @@ -314,7 +314,7 @@ impl CosmicTextSystemState { let bitmap_size = glyph_bounds.size; let font = &self.loaded_fonts_store[params.font_id.0]; let font_system = &mut self.font_system; - let image = self + let mut image = self .swash_cache .get_image( font_system, @@ -330,6 +330,13 @@ impl CosmicTextSystemState { .clone() .unwrap(); + if params.is_emoji { + // Convert from RGBA to BGRA. + for pixel in image.data.chunks_exact_mut(4) { + pixel.swap(0, 2); + } + } + Ok((bitmap_size, image.data)) } } @@ -394,13 +401,20 @@ impl CosmicTextSystemState { for glyph in &layout.glyphs { let font_id = glyph.font_id; let font_id = self.font_id_for_cosmic_id(font_id); + let is_emoji = self.is_emoji(font_id); let mut glyphs = SmallVec::new(); + + // HACK: Prevent crash caused by variation selectors. + if glyph.glyph_id == 3 && is_emoji { + continue; + } + // todo(linux) this is definitely wrong, each glyph in glyphs from cosmic-text is a cluster with one glyph, ShapedRun takes a run of glyphs with the same font and direction glyphs.push(ShapedGlyph { id: GlyphId(glyph.glyph_id as u32), position: point((glyph.x).into(), glyph.y.into()), index: glyph.start, - is_emoji: self.is_emoji(font_id), + is_emoji, }); runs.push(crate::ShapedRun { font_id, glyphs });