#300: emoji take a colour face before a style face without colour glyphs (DejaVu Sans on Linux drew them in one colour); the scale test allows faces wider than the em

This commit is contained in:
bflatastic
2026-10-15 19:59:24 +07:00
parent a89031eab2
commit ff3981de73
2 changed files with 13 additions and 6 deletions
+4 -3
View File
@@ -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);
+9 -3
View File
@@ -360,12 +360,18 @@ pub fn layout(text: &TextData, box_width: Option<f64>, box_height: Option<f64>)
let mut seg_start = *start;
while seg_start < *end {
let face_for = |c: char| -> Arc<Face> {
// 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);