diff --git a/src/display/mod.rs b/src/display/mod.rs index cc628dd..204b491 100644 --- a/src/display/mod.rs +++ b/src/display/mod.rs @@ -125,11 +125,11 @@ pub struct TextDisplay { fn size_of_elts() { use std::mem::size_of; assert_eq!(size_of::>(), 24); - assert_eq!(size_of::(), 120); + assert_eq!(size_of::(), 112); assert_eq!(size_of::(), 24); assert_eq!(size_of::(), 24); #[cfg(not(feature = "num_glyphs"))] - assert_eq!(size_of::(), 208); + assert_eq!(size_of::(), 200); #[cfg(feature = "num_glyphs")] assert_eq!(size_of::(), 216); } diff --git a/src/display/text_runs.rs b/src/display/text_runs.rs index d5a1be2..d61623a 100644 --- a/src/display/text_runs.rs +++ b/src/display/text_runs.rs @@ -9,13 +9,14 @@ use super::TextDisplay; use crate::conv::{to_u32, to_usize}; -use crate::fonts::{self, FontSelector, NoFontMatch}; +use crate::fonts::{self, FaceId, FontSelector, NoFontMatch}; use crate::format::FormattableText; use crate::util::ends_with_hard_break; use crate::{Direction, Range, shaper}; -use icu_properties::props::{EmojiPresentation, Script}; +use icu_properties::props::{Emoji, EmojiModifier, RegionalIndicator, Script}; use icu_properties::{CodePointMapData, CodePointSetData}; use icu_segmenter::LineSegmenter; +use std::sync::OnceLock; use unicode_bidi::{BidiInfo, LTR_LEVEL, RTL_LEVEL}; #[derive(Clone, Copy, Debug, PartialEq)] @@ -80,7 +81,7 @@ impl TextDisplay { first_real: Option, ) -> Result<(), NoFontMatch> { let fonts = fonts::library(); - let font_id = fonts.select_font(&font, input.script)?; + let font_id = fonts.select_font(&font, input.script.into())?; let text = &input.text[range.to_std()]; // Find a font face @@ -120,8 +121,13 @@ impl TextDisplay { } let rest = breaks.split_off(j); - self.runs - .push(shaper::shape(input, sub_range, face, breaks, special)); + self.runs.push(shaper::shape( + input, + sub_range, + face, + breaks, + RunSpecial::NoBreak, + )); breaks = rest; start = index; } @@ -197,7 +203,7 @@ impl TextDisplay { text, dpem, level: levels.first().cloned().unwrap_or(LTR_LEVEL), - script: Script::Unknown.into(), + script: Script::Unknown, }; let mut start = 0; @@ -209,36 +215,76 @@ impl TextDisplay { let mut next_break = break_iter.next(); let mut first_real = None; - let emoji_presentation = CodePointSetData::new::(); + let mut emoji_state = EmojiState::None; + let mut emoji_start = 0; + let mut emoji_end = 0; let mut last_is_control = false; let mut last_is_htab = false; - let mut last_is_emoji = false; let mut non_control_end = 0; - for (index, c) in text.char_indices() { + for (index, c) in text + .char_indices() + .chain(std::iter::once((text.len(), '\0'))) + { // Handling for control chars if !last_is_control { non_control_end = index; } let is_control = c.is_control(); let is_htab = c == '\t'; - let mut require_break = is_htab || (last_is_control && !is_control); - - let script = CodePointMapData::