diff --git a/crates/text/src/color_tests.rs b/crates/text/src/color_tests.rs index fa92298b..9ccf0b9c 100644 --- a/crates/text/src/color_tests.rs +++ b/crates/text/src/color_tests.rs @@ -185,8 +185,8 @@ fn colour_emoji_carry_their_own_pixels() { #[test] fn emoji_in_plain_text_draw_from_a_colour_face() { - // A symbol font among the fallbacks (Windows has one) draws U+1F600 in one colour: the emoji - // face comes first for it. + // The style's own face (DejaVu Sans on Linux) or a symbol font among the fallbacks (Windows has + // one) draws U+1F600 in one colour: the emoji face comes first for it. if emoji_face().is_none() { return; } @@ -207,7 +207,8 @@ fn glyphs_place_their_ink_at_a_scale() { assert!(g.color(2.0).is_some(), "the emoji glyph has ink"); return; }; - assert!(bitmap.width >= 32 && bitmap.width <= 65, "{} px at 2:1", bitmap.width); + // Some emoji faces draw wider than the em (Noto Color Emoji's strikes are about 1.25 em). + assert!(bitmap.width >= 32 && bitmap.width <= 96, "{} px at 2:1", bitmap.width); let corner = place * figcraft_geom::Point::new(0.0, 0.0); assert!(corner.x >= g.x - g.size && corner.x <= g.x + g.size, "x {} vs pen {}", corner.x, g.x); assert!(corner.y >= g.y - g.size && corner.y <= g.y + g.size, "y {} vs baseline {}", corner.y, g.y); diff --git a/crates/text/src/layout.rs b/crates/text/src/layout.rs index dcd1eed2..836fe6a7 100644 --- a/crates/text/src/layout.rs +++ b/crates/text/src/layout.rs @@ -360,12 +360,18 @@ pub fn layout(text: &TextData, box_width: Option, box_height: Option) let mut seg_start = *start; while seg_start < *end { let face_for = |c: char| -> Arc { + // Emoji take a colour face before a face without colour glyphs (the style's own or a + // symbol font), which would draw them in one colour. + if is_emoji(c) + && !primary.has_color() + && let Some(f) = emoji.iter().find(|f| f.has_char(c)) + { + return f.clone(); + } if c == '\n' || primary.has_char(c) { return primary.clone(); } - // Emoji take a colour face before the symbol fonts, which draw many of them in one colour. - let colour = if is_emoji(c) { emoji.iter().find(|f| f.has_char(c)) } else { None }; - colour.or_else(|| fallbacks.iter().find(|f| f.has_char(c))).cloned().unwrap_or_else(|| primary.clone()) + fallbacks.iter().find(|f| f.has_char(c)).cloned().unwrap_or_else(|| primary.clone()) }; let first = chars.get(seg_start).copied().unwrap_or(' '); let face = face_for(first);