Add font_load() fn
This commit is contained in:
parent
d617eaaf64
commit
b7df68195a
|
@ -35,13 +35,14 @@ impl PanelImpl for DummyPanel {
|
|||
let ctx = draw::DrawContext::new(self.panel);
|
||||
self.menu.draw(&ctx);
|
||||
|
||||
let text = "Hello, world!";
|
||||
let font = Font::new("Iosevka Nerd Font");
|
||||
let text = "";
|
||||
let bg = Color::MAGENTA;
|
||||
let fg = Color::BLACK;
|
||||
let scale = 0.1;
|
||||
let pos = Vec2::ZERO;
|
||||
|
||||
let layout = TextLayout::new(text);
|
||||
let layout = TextLayout::new(&font, text);
|
||||
let bounds = layout.get_bounds();
|
||||
let bounds = draw::Rect {
|
||||
bl: Vec2::from(bounds.bl) * scale,
|
||||
|
|
|
@ -133,12 +133,28 @@ impl Panel {
|
|||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Font(u32);
|
||||
|
||||
impl Font {
|
||||
pub fn new(family: &str) -> Self {
|
||||
unsafe { Self(font_load(family.as_ptr() as u32, family.len() as u32)) }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct TextLayout(u32);
|
||||
|
||||
impl TextLayout {
|
||||
pub fn new(text: &str) -> Self {
|
||||
unsafe { Self(text_layout_new(text.as_ptr() as u32, text.len() as u32)) }
|
||||
pub fn new(font: &Font, text: &str) -> Self {
|
||||
unsafe {
|
||||
Self(text_layout_new(
|
||||
font.0,
|
||||
text.as_ptr() as u32,
|
||||
text.len() as u32,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_bounds(&self) -> Rect {
|
||||
|
@ -182,7 +198,9 @@ extern "C" {
|
|||
a: f32,
|
||||
);
|
||||
|
||||
fn text_layout_new(text_ptr: u32, text_len: u32) -> u32;
|
||||
fn font_load(family_ptr: u32, family_len: u32) -> u32;
|
||||
|
||||
fn text_layout_new(font_id: u32, text_ptr: u32, text_len: u32) -> u32;
|
||||
fn text_layout_delete(id: u32);
|
||||
fn text_layout_get_bounds(id: u32, rect_ptr: u32);
|
||||
fn text_layout_get_glyphs_num(id: u32) -> u32;
|
||||
|
|
45
src/lib.rs
45
src/lib.rs
|
@ -1,6 +1,8 @@
|
|||
pub use canary_types::*;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use slab::Slab;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub mod text;
|
||||
|
||||
|
@ -14,7 +16,9 @@ pub trait ScriptAbi {
|
|||
fn draw_glyphs(&self, glyphs: &[GlyphPosition], offset: Vec2, scale: f32, color: Color);
|
||||
fn with_draw_commands(&self, f: impl FnOnce(&[DrawCommand]));
|
||||
|
||||
fn text_layout_new(&self, text: &str) -> u32;
|
||||
fn font_load(&self, family: &str) -> u32;
|
||||
|
||||
fn text_layout_new(&self, font_id: u32, text: &str) -> u32;
|
||||
fn text_layout_delete(&self, id: u32);
|
||||
fn text_layout_get_bounds(&self, id: u32, rect: &mut Rect);
|
||||
fn text_layout_get_glyphs_num(&self, id: u32) -> u32;
|
||||
|
@ -122,12 +126,21 @@ impl<T: ScriptAbi> WasmtimeScript<T> {
|
|||
},
|
||||
)?;
|
||||
|
||||
linker.func_wrap(
|
||||
module,
|
||||
"font_load",
|
||||
|mut caller: wasmtime::Caller<'_, T>, family_ptr: u32, family_len: u32| {
|
||||
let family = Self::get_memory_slice_str(&mut caller, family_ptr, family_len);
|
||||
caller.data().font_load(family)
|
||||
},
|
||||
)?;
|
||||
|
||||
linker.func_wrap(
|
||||
module,
|
||||
"text_layout_new",
|
||||
|mut caller: wasmtime::Caller<'_, T>, text_ptr: u32, text_len: u32| {
|
||||
|mut caller: wasmtime::Caller<'_, T>, font_id: u32, text_ptr: u32, text_len: u32| {
|
||||
let text = Self::get_memory_slice_str(&mut caller, text_ptr, text_len);
|
||||
caller.data().text_layout_new(text)
|
||||
caller.data().text_layout_new(font_id, text)
|
||||
},
|
||||
)?;
|
||||
|
||||
|
@ -235,6 +248,8 @@ impl<T: ScriptAbi> ScriptInstance for WasmtimeScript<T> {
|
|||
pub struct ScriptAbiImpl {
|
||||
draw_cmds: Mutex<Vec<DrawCommand>>,
|
||||
font_store: text::FontStore,
|
||||
font_families: Mutex<HashMap<String, u32>>,
|
||||
loaded_fonts: RwLock<Vec<Arc<text::Font>>>,
|
||||
text_layouts: RwLock<Slab<text::TextLayout>>,
|
||||
}
|
||||
|
||||
|
@ -252,7 +267,9 @@ impl ScriptAbi for ScriptAbiImpl {
|
|||
}
|
||||
|
||||
fn draw_glyphs(&self, glyphs: &[GlyphPosition], offset: Vec2, scale: f32, color: Color) {
|
||||
let font = self.font_store.load_font("Liberation Sans");
|
||||
// TODO multiple fonts per layout
|
||||
let loaded = self.loaded_fonts.read();
|
||||
let font = loaded.get(glyphs[0].face as usize).unwrap();
|
||||
let cmds = font.draw(glyphs, offset, scale, color);
|
||||
self.draw_cmds.lock().extend(cmds.into_iter());
|
||||
}
|
||||
|
@ -261,8 +278,24 @@ impl ScriptAbi for ScriptAbiImpl {
|
|||
f(self.draw_cmds.lock().as_slice());
|
||||
}
|
||||
|
||||
fn text_layout_new(&self, text: &str) -> u32 {
|
||||
let font = self.font_store.load_font("Liberation Sans");
|
||||
fn font_load(&self, family: &str) -> u32 {
|
||||
let mut family_cache = self.font_families.lock();
|
||||
|
||||
if let Some(cached) = family_cache.get(family) {
|
||||
return *cached;
|
||||
}
|
||||
|
||||
let font = self.font_store.load_font(family);
|
||||
let mut loaded = self.loaded_fonts.write();
|
||||
let id = loaded.len() as u32;
|
||||
family_cache.insert(family.to_string(), id);
|
||||
loaded.push(font);
|
||||
id
|
||||
}
|
||||
|
||||
fn text_layout_new(&self, font_id: u32, text: &str) -> u32 {
|
||||
let loaded = self.loaded_fonts.read();
|
||||
let font = loaded.get(font_id as usize).unwrap();
|
||||
let layout = font.shape(text);
|
||||
self.text_layouts.write().insert(layout) as u32
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue