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 surfaces: Surfaces,
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 viewbox: Viewbox,
pub images: ImageStore,
@ -117,7 +113,6 @@ impl RenderState {
// This is used multiple times everywhere so instead of creating new instances every
// time we reuse this one.
RenderState {
gpu_state,
surfaces,
@ -140,6 +135,7 @@ impl RenderState {
pub fn fonts(&self) -> &FontStore {
&self.fonts
}
pub fn fonts_mut(&mut self) -> &mut FontStore {
&mut self.fonts
}

View file

@ -3,6 +3,9 @@ use skia_safe::{self as skia, textlayout, FontMgr};
use crate::shapes::FontFamily;
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 {
// TODO: we should probably have just one of those
@ -18,7 +21,13 @@ impl FontStore {
.new_from_data(DEFAULT_FONT_BYTES, None)
.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();
font_collection.set_default_font_manager(FontMgr::default(), None);
@ -50,6 +59,7 @@ impl FontStore {
self.font_provider
.register_typeface(typeface, alias.as_str());
self.refresh_font_collection();
Ok(())

View file

@ -1,7 +1,10 @@
use crate::math::Rect;
use crate::{
math::Rect,
render::{DEFAULT_EMOJI_FONT, DEFAULT_FONT},
};
use skia_safe::{
self as skia,
textlayout::{FontCollection, ParagraphBuilder},
textlayout::{FontCollection, ParagraphBuilder, ParagraphStyle},
};
use super::FontFamily;
@ -57,7 +60,7 @@ impl TextContent {
}
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
paragraph_style.set_text_direction(skia::textlayout::TextDirection::LTR);
@ -65,11 +68,14 @@ impl TextContent {
.iter()
.map(|p| {
let mut builder = ParagraphBuilder::new(&paragraph_style, fonts);
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.pop();
}
builder.build()
})
.collect()
@ -122,8 +128,11 @@ impl TextLeaf {
let mut style = skia::textlayout::TextStyle::default();
style.set_color(skia::Color::BLACK);
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
}