mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
fonts: Respect emoji variation selector when selecting fonts (#32493)
This uses a pretty simple heuristic to select a font likely to contain
color emoji. In the future Servo should actually check if the font also
contains a color representation of the character in question. For now
the code assumes that when a font supports color glyphs of some kind and
supports the character in question at all, it supports the color
version.
This fixes support for rendering keycap emoji clusters such as 1️⃣ .
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Rakhi Sharma <atbrakhi@igalia.com>
Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
This commit is contained in:
parent
79cd87a3c3
commit
57b64d8123
9 changed files with 87 additions and 28 deletions
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use unicode_properties::{emoji, UnicodeEmoji};
|
||||
use unicode_properties::{emoji, EmojiStatus, UnicodeEmoji};
|
||||
|
||||
pub use crate::text::shaping::Shaper;
|
||||
|
||||
|
@ -10,31 +10,59 @@ pub mod glyph;
|
|||
pub mod shaping;
|
||||
pub mod util;
|
||||
|
||||
/// Whether or not font fallback selection prefers the emoji or text representation
|
||||
/// of a character. If `None` then either presentation is acceptable.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum EmojiPresentationPreference {
|
||||
None,
|
||||
Text,
|
||||
Emoji,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct FallbackFontSelectionOptions {
|
||||
pub character: char,
|
||||
pub prefer_emoji_presentation: bool,
|
||||
pub presentation_preference: EmojiPresentationPreference,
|
||||
}
|
||||
|
||||
impl Default for FallbackFontSelectionOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
character: ' ',
|
||||
prefer_emoji_presentation: false,
|
||||
presentation_preference: EmojiPresentationPreference::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FallbackFontSelectionOptions {
|
||||
pub fn new(character: char, next_character: Option<char>) -> Self {
|
||||
let prefer_emoji_presentation = match next_character {
|
||||
Some(next_character) if emoji::is_emoji_presentation_selector(next_character) => true,
|
||||
Some(next_character) if emoji::is_text_presentation_selector(next_character) => false,
|
||||
_ => character.is_emoji_char(),
|
||||
let presentation_preference = match next_character {
|
||||
Some(next_character) if emoji::is_emoji_presentation_selector(next_character) => {
|
||||
EmojiPresentationPreference::Emoji
|
||||
},
|
||||
Some(next_character) if emoji::is_text_presentation_selector(next_character) => {
|
||||
EmojiPresentationPreference::Text
|
||||
},
|
||||
// We don't want to select emoji prsentation for any possible character that might be an emoji, because
|
||||
// that includes characters such as '0' that are also used outside of emoji clusters. Instead, only
|
||||
// select the emoji font for characters that explicitly have an emoji presentation (in the absence
|
||||
// of the emoji presentation selectors above).
|
||||
_ if matches!(
|
||||
character.emoji_status(),
|
||||
EmojiStatus::EmojiPresentation |
|
||||
EmojiStatus::EmojiPresentationAndModifierBase |
|
||||
EmojiStatus::EmojiPresentationAndEmojiComponent |
|
||||
EmojiStatus::EmojiPresentationAndModifierAndEmojiComponent
|
||||
) =>
|
||||
{
|
||||
EmojiPresentationPreference::Emoji
|
||||
},
|
||||
_ if character.is_emoji_char() => EmojiPresentationPreference::Text,
|
||||
_ => EmojiPresentationPreference::None,
|
||||
};
|
||||
Self {
|
||||
character,
|
||||
prefer_emoji_presentation,
|
||||
presentation_preference,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue