mirror of
https://github.com/penpot/penpot.git
synced 2025-06-11 22:01:38 +02:00
🎉 Store custom fonts (ttfs) and use them to write texts (wasm) (#6050)
This commit is contained in:
parent
e4c9b736f7
commit
eb6d2fb0eb
14 changed files with 386 additions and 140 deletions
|
@ -23,18 +23,17 @@ fn render_debug_view(render_state: &mut RenderState) {
|
|||
}
|
||||
|
||||
pub fn render_wasm_label(render_state: &mut RenderState) {
|
||||
let canvas = render_state.surfaces.canvas(SurfaceId::Current);
|
||||
let font_provider = render_state.fonts().font_provider();
|
||||
let typeface = font_provider
|
||||
.match_family_style("robotomono-regular", skia::FontStyle::default())
|
||||
.unwrap();
|
||||
|
||||
let canvas = render_state.surfaces.canvas(SurfaceId::Current);
|
||||
let skia::ISize { width, height } = canvas.base_layer_size();
|
||||
let p = skia::Point::new(width as f32 - 100.0, height as f32 - 25.0);
|
||||
let mut paint = skia::Paint::default();
|
||||
paint.set_color(skia::Color::from_argb(100, 0, 0, 0));
|
||||
|
||||
let font_provider = &render_state.font_provider;
|
||||
let typeface = font_provider
|
||||
.match_family_style("robotomono-regular", skia::FontStyle::default())
|
||||
.unwrap();
|
||||
|
||||
let font = skia::Font::new(typeface, 10.0);
|
||||
canvas.draw_str("WASM RENDERER", p, &font, &paint);
|
||||
}
|
||||
|
|
70
render-wasm/src/render/fonts.rs
Normal file
70
render-wasm/src/render/fonts.rs
Normal file
|
@ -0,0 +1,70 @@
|
|||
use skia_safe::{self as skia, textlayout, FontMgr};
|
||||
|
||||
use crate::shapes::FontFamily;
|
||||
|
||||
const DEFAULT_FONT_BYTES: &[u8] = include_bytes!("../fonts/RobotoMono-Regular.ttf");
|
||||
|
||||
pub struct FontStore {
|
||||
// TODO: we should probably have just one of those
|
||||
font_provider: textlayout::TypefaceFontProvider,
|
||||
font_collection: textlayout::FontCollection,
|
||||
}
|
||||
|
||||
impl FontStore {
|
||||
pub fn new() -> Self {
|
||||
let mut font_provider = skia::textlayout::TypefaceFontProvider::new();
|
||||
|
||||
let default_font = skia::FontMgr::default()
|
||||
.new_from_data(DEFAULT_FONT_BYTES, None)
|
||||
.expect("Failed to load font");
|
||||
|
||||
font_provider.register_typeface(default_font, "robotomono-regular");
|
||||
|
||||
let mut font_collection = skia::textlayout::FontCollection::new();
|
||||
font_collection.set_default_font_manager(FontMgr::default(), None);
|
||||
font_collection.set_dynamic_font_manager(FontMgr::from(font_provider.clone()));
|
||||
|
||||
Self {
|
||||
font_provider,
|
||||
font_collection,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn font_provider(&self) -> &textlayout::TypefaceFontProvider {
|
||||
&self.font_provider
|
||||
}
|
||||
|
||||
pub fn font_collection(&self) -> &textlayout::FontCollection {
|
||||
&self.font_collection
|
||||
}
|
||||
|
||||
pub fn add(&mut self, family: FontFamily, font_data: &[u8]) -> Result<(), String> {
|
||||
if self.has_family(&family) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let alias = format!("{}", family);
|
||||
let typeface = skia::FontMgr::default()
|
||||
.new_from_data(font_data, None)
|
||||
.ok_or("Failed to create typeface")?;
|
||||
|
||||
self.font_provider
|
||||
.register_typeface(typeface, alias.as_str());
|
||||
self.refresh_font_collection();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn has_family(&self, family: &FontFamily) -> bool {
|
||||
let serialized = format!("{}", family);
|
||||
self.font_provider.family_names().any(|x| x == serialized)
|
||||
}
|
||||
|
||||
fn refresh_font_collection(&mut self) {
|
||||
self.font_collection = skia::textlayout::FontCollection::new();
|
||||
self.font_collection
|
||||
.set_default_font_manager(FontMgr::default(), None);
|
||||
self.font_collection
|
||||
.set_dynamic_font_manager(FontMgr::from(self.font_provider.clone()));
|
||||
}
|
||||
}
|
|
@ -3,8 +3,9 @@ use crate::shapes::TextContent;
|
|||
|
||||
pub fn render(render_state: &mut RenderState, text: &TextContent) {
|
||||
let mut offset_y = 0.0;
|
||||
for mut skia_paragraph in text.to_paragraphs(&render_state.font_collection) {
|
||||
for mut skia_paragraph in text.to_paragraphs(&render_state.fonts().font_collection()) {
|
||||
skia_paragraph.layout(text.width());
|
||||
|
||||
let xy = (text.x(), text.y() + offset_y);
|
||||
skia_paragraph.paint(render_state.surfaces.canvas(SurfaceId::Fills), xy);
|
||||
offset_y += skia_paragraph.height();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue