Support emoji default font in text rendering

This commit is contained in:
Elena Torro 2025-03-17 15:14:58 +01:00
parent fa0da3a695
commit ba387a892f
4 changed files with 27 additions and 12 deletions

Binary file not shown.

View file

@ -86,10 +86,6 @@ pub(crate) struct RenderState {
pub options: RenderOptions, pub options: RenderOptions,
pub surfaces: Surfaces, pub surfaces: Surfaces,
fonts: FontStore, fonts: FontStore,
// TODO: we should probably have only one of these
// pub font_provider: skia::textlayout::TypefaceFontProvider,
// pub font_collection: skia::textlayout::FontCollection,
// ----
pub cached_surface_image: Option<CachedSurfaceImage>, pub cached_surface_image: Option<CachedSurfaceImage>,
pub viewbox: Viewbox, pub viewbox: Viewbox,
pub images: ImageStore, pub images: ImageStore,
@ -117,7 +113,6 @@ impl RenderState {
// This is used multiple times everywhere so instead of creating new instances every // This is used multiple times everywhere so instead of creating new instances every
// time we reuse this one. // time we reuse this one.
RenderState { RenderState {
gpu_state, gpu_state,
surfaces, surfaces,
@ -140,6 +135,7 @@ impl RenderState {
pub fn fonts(&self) -> &FontStore { pub fn fonts(&self) -> &FontStore {
&self.fonts &self.fonts
} }
pub fn fonts_mut(&mut self) -> &mut FontStore { pub fn fonts_mut(&mut self) -> &mut FontStore {
&mut self.fonts &mut self.fonts
} }

View file

@ -3,6 +3,9 @@ use skia_safe::{self as skia, textlayout, FontMgr};
use crate::shapes::FontFamily; use crate::shapes::FontFamily;
const DEFAULT_FONT_BYTES: &[u8] = include_bytes!("../fonts/RobotoMono-Regular.ttf"); const DEFAULT_FONT_BYTES: &[u8] = include_bytes!("../fonts/RobotoMono-Regular.ttf");
const EMOJI_FONT_BYTES: &[u8] = include_bytes!("../fonts/NotoColorEmoji-Regular.ttf");
pub static DEFAULT_FONT: &'static str = "robotomono-regular";
pub static DEFAULT_EMOJI_FONT: &'static str = "noto-color-emoji";
pub struct FontStore { pub struct FontStore {
// TODO: we should probably have just one of those // TODO: we should probably have just one of those
@ -18,7 +21,13 @@ impl FontStore {
.new_from_data(DEFAULT_FONT_BYTES, None) .new_from_data(DEFAULT_FONT_BYTES, None)
.expect("Failed to load font"); .expect("Failed to load font");
font_provider.register_typeface(default_font, "robotomono-regular"); font_provider.register_typeface(default_font, DEFAULT_FONT);
let emoji_font = skia::FontMgr::default()
.new_from_data(EMOJI_FONT_BYTES, None)
.expect("Failed to load font");
font_provider.register_typeface(emoji_font, DEFAULT_EMOJI_FONT);
let mut font_collection = skia::textlayout::FontCollection::new(); let mut font_collection = skia::textlayout::FontCollection::new();
font_collection.set_default_font_manager(FontMgr::default(), None); font_collection.set_default_font_manager(FontMgr::default(), None);
@ -50,6 +59,7 @@ impl FontStore {
self.font_provider self.font_provider
.register_typeface(typeface, alias.as_str()); .register_typeface(typeface, alias.as_str());
self.refresh_font_collection(); self.refresh_font_collection();
Ok(()) Ok(())

View file

@ -1,7 +1,10 @@
use crate::math::Rect; use crate::{
math::Rect,
render::{DEFAULT_EMOJI_FONT, DEFAULT_FONT},
};
use skia_safe::{ use skia_safe::{
self as skia, self as skia,
textlayout::{FontCollection, ParagraphBuilder}, textlayout::{FontCollection, ParagraphBuilder, ParagraphStyle},
}; };
use super::FontFamily; use super::FontFamily;
@ -57,7 +60,7 @@ impl TextContent {
} }
pub fn to_paragraphs(&self, fonts: &FontCollection) -> Vec<skia::textlayout::Paragraph> { pub fn to_paragraphs(&self, fonts: &FontCollection) -> Vec<skia::textlayout::Paragraph> {
let mut paragraph_style = skia::textlayout::ParagraphStyle::default(); let mut paragraph_style = ParagraphStyle::default();
// TODO: read text direction, align, etc. from the shape // TODO: read text direction, align, etc. from the shape
paragraph_style.set_text_direction(skia::textlayout::TextDirection::LTR); paragraph_style.set_text_direction(skia::textlayout::TextDirection::LTR);
@ -65,11 +68,14 @@ impl TextContent {
.iter() .iter()
.map(|p| { .map(|p| {
let mut builder = ParagraphBuilder::new(&paragraph_style, fonts); let mut builder = ParagraphBuilder::new(&paragraph_style, fonts);
for leaf in &p.children { for leaf in &p.children {
builder.push_style(&leaf.to_style()); let text_style = leaf.to_style();
builder.push_style(&text_style);
builder.add_text(&leaf.text); builder.add_text(&leaf.text);
builder.pop(); builder.pop();
} }
builder.build() builder.build()
}) })
.collect() .collect()
@ -122,8 +128,11 @@ impl TextLeaf {
let mut style = skia::textlayout::TextStyle::default(); let mut style = skia::textlayout::TextStyle::default();
style.set_color(skia::Color::BLACK); style.set_color(skia::Color::BLACK);
style.set_font_size(self.font_size); style.set_font_size(self.font_size);
style.set_font_families(&[self.serialized_font_family()]); style.set_font_families(&[
self.serialized_font_family(),
DEFAULT_FONT.to_string(),
DEFAULT_EMOJI_FONT.to_string(),
]);
style style
} }