From 16c77faae6ccbc351d50c95f7723c6a8085e3aba Mon Sep 17 00:00:00 2001 From: Chad Brokaw Date: Wed, 22 May 2024 00:52:57 +0200 Subject: [PATCH 1/4] add emoji family for emoji clusters Quick and dirty fallback for emoji. This can be done more efficiently (and should be handled in fontique directly) but this should get us functioning emoji mapping for capable renderers. --- src/shape.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/shape.rs b/src/shape.rs index f7bcaac9..cdbd73b5 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -10,7 +10,7 @@ use super::style::{Brush, FontFeature, FontVariation}; use crate::util::nearly_eq; #[cfg(feature = "std")] use crate::Font; -use fontique::{self, Attributes, Query, QueryFont}; +use fontique::{self, Attributes, Query, QueryFamily, QueryFont}; use swash::shape::*; #[cfg(feature = "std")] use swash::text::cluster::{CharCluster, CharInfo, Token}; @@ -223,7 +223,15 @@ impl<'a, 'b, B: Brush> partition::Selector for FontSelector<'a, 'b, B> { }; let variations = self.rcx.variations(style.font_variations).unwrap_or(&[]); let features = self.rcx.features(style.font_features).unwrap_or(&[]); - if self.fonts_id != Some(fonts_id) { + if cluster.info().is_emoji() { + let fonts = self.rcx.stack(style.font_stack).unwrap_or(&[]); + let fonts = fonts.iter().map(|id| QueryFamily::Id(*id)); + self.query + .set_families(fonts.chain(core::iter::once(QueryFamily::Generic( + fontique::GenericFamily::Emoji, + )))); + self.fonts_id = None; + } else if self.fonts_id != Some(fonts_id) { let fonts = self.rcx.stack(style.font_stack).unwrap_or(&[]); self.query.set_families(fonts.iter().copied()); self.fonts_id = Some(fonts_id); From b0e6520865411f01a078d8ba327c7a4296846e65 Mon Sep 17 00:00:00 2001 From: Chad Brokaw Date: Wed, 22 May 2024 01:00:58 +0200 Subject: [PATCH 2/4] clippy --- src/shape.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shape.rs b/src/shape.rs index cdbd73b5..b04f044c 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -10,7 +10,7 @@ use super::style::{Brush, FontFeature, FontVariation}; use crate::util::nearly_eq; #[cfg(feature = "std")] use crate::Font; -use fontique::{self, Attributes, Query, QueryFamily, QueryFont}; +use fontique::{self, Attributes, Query, QueryFont}; use swash::shape::*; #[cfg(feature = "std")] use swash::text::cluster::{CharCluster, CharInfo, Token}; @@ -211,6 +211,7 @@ impl<'a, 'b, B: Brush> partition::Selector for FontSelector<'a, 'b, B> { type SelectedFont = SelectedFont; fn select_font(&mut self, cluster: &mut CharCluster) -> Option { + use fontique::QueryFamily; let style_index = cluster.user_data() as u16; if style_index != self.style_index { self.style_index = style_index; From 96371b14bd2e7e458f71ab05bacbfd32fe5bd867 Mon Sep 17 00:00:00 2001 From: Chad Brokaw Date: Wed, 22 May 2024 09:44:04 +0200 Subject: [PATCH 3/4] capture emoji state in outer condition --- src/shape.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/shape.rs b/src/shape.rs index b04f044c..66a1036b 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -213,7 +213,8 @@ impl<'a, 'b, B: Brush> partition::Selector for FontSelector<'a, 'b, B> { fn select_font(&mut self, cluster: &mut CharCluster) -> Option { use fontique::QueryFamily; let style_index = cluster.user_data() as u16; - if style_index != self.style_index { + let is_emoji = cluster.info().is_emoji(); + if style_index != self.style_index || is_emoji { self.style_index = style_index; let style = &self.styles[style_index as usize].style; let fonts_id = style.font_stack.id(); @@ -224,7 +225,7 @@ impl<'a, 'b, B: Brush> partition::Selector for FontSelector<'a, 'b, B> { }; let variations = self.rcx.variations(style.font_variations).unwrap_or(&[]); let features = self.rcx.features(style.font_features).unwrap_or(&[]); - if cluster.info().is_emoji() { + if is_emoji { let fonts = self.rcx.stack(style.font_stack).unwrap_or(&[]); let fonts = fonts.iter().map(|id| QueryFamily::Id(*id)); self.query From 01e393d774542b23e19b60ca8ff722693ce9386b Mon Sep 17 00:00:00 2001 From: Chad Brokaw Date: Wed, 22 May 2024 17:44:24 +0200 Subject: [PATCH 4/4] check self.fonts_id in select_font() Forces a reset after we push a specialized font stack for an emoji cluster --- src/shape.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/shape.rs b/src/shape.rs index 66a1036b..1b30492a 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -10,6 +10,8 @@ use super::style::{Brush, FontFeature, FontVariation}; use crate::util::nearly_eq; #[cfg(feature = "std")] use crate::Font; +#[cfg(feature = "std")] +use fontique::QueryFamily; use fontique::{self, Attributes, Query, QueryFont}; use swash::shape::*; #[cfg(feature = "std")] @@ -211,10 +213,9 @@ impl<'a, 'b, B: Brush> partition::Selector for FontSelector<'a, 'b, B> { type SelectedFont = SelectedFont; fn select_font(&mut self, cluster: &mut CharCluster) -> Option { - use fontique::QueryFamily; let style_index = cluster.user_data() as u16; let is_emoji = cluster.info().is_emoji(); - if style_index != self.style_index || is_emoji { + if style_index != self.style_index || is_emoji || self.fonts_id.is_none() { self.style_index = style_index; let style = &self.styles[style_index as usize].style; let fonts_id = style.font_stack.id();