From 6b78d51e64c6cce3986fd6d43404a0e4e3a09430 Mon Sep 17 00:00:00 2001 From: marceline-cramer Date: Mon, 18 Jul 2022 16:03:02 -0600 Subject: [PATCH] GlyphCache mutex-locking + Font interior mutability --- src/text.rs | 97 +++++++++++++++++++++++++---------------------------- 1 file changed, 46 insertions(+), 51 deletions(-) diff --git a/src/text.rs b/src/text.rs index f6fe6b0..1f7e3ed 100644 --- a/src/text.rs +++ b/src/text.rs @@ -19,23 +19,14 @@ const TEXT_SCALE: f32 = 0.075; pub struct GlyphCache { units_per_em: f32, - glyphs: Vec, + glyphs: RwLock>, } impl GlyphCache { - pub fn empty() -> Self { - Self { - units_per_em: 0.0, - glyphs: Vec::new(), - } - } - - pub fn load_paths(&mut self, font: &AllsortsFont) { + pub fn new(font: &AllsortsFont) -> Self { let glyph_num = font.num_glyphs(); - self.glyphs.clear(); - self.glyphs.reserve(glyph_num as usize); - - self.units_per_em = font.head_table().unwrap().unwrap().units_per_em as f32; + let mut glyphs = Vec::with_capacity(glyph_num as usize); + let units_per_em = font.head_table().unwrap().unwrap().units_per_em as f32; if font.glyph_table_flags.contains(GlyphTableFlags::CFF) && font.font_table_provider.sfnt_version() == tag::OTTO @@ -43,8 +34,7 @@ impl GlyphCache { let cff_data = font.font_table_provider.read_table_data(tag::CFF).unwrap(); let mut cff = ReadScope::new(&cff_data).read::>().unwrap(); for index in 0..glyph_num { - self.glyphs - .push(CachedGlyph::new(self.units_per_em, &mut cff, index)); + glyphs.push(CachedGlyph::new(units_per_em, &mut cff, index)); } } else if font.glyph_table_flags.contains(GlyphTableFlags::GLYF) { let loca_data = font.font_table_provider.read_table_data(tag::LOCA).unwrap(); @@ -60,32 +50,15 @@ impl GlyphCache { .unwrap(); for index in 0..glyph_num { - self.glyphs - .push(CachedGlyph::new(self.units_per_em, &mut glyf, index)); + glyphs.push(CachedGlyph::new(units_per_em, &mut glyf, index)); } } else { panic!("no glyf or CFF table"); } - } - pub fn draw(&mut self, mesh: &mut DummyText, index: u16, xpos: i32, ypos: i32, yoff: f32) { - let glyph = self.glyphs.get_mut(index as usize).unwrap().get_mesh(); - let voff = mesh.vertices.len() as MeshIndex; - let scale = TEXT_SCALE / self.units_per_em; - let xpos = xpos as f32 * scale; - let ypos = ypos as f32 * scale; - - for v in glyph.vertices.iter() { - let x = v.position.x + xpos - 0.9; - let y = v.position.y + ypos + yoff; - mesh.vertices.push(MeshVertex { - position: canary_types::Vec2 { x, y }, - color: v.color, - }); - } - - for i in glyph.indices.iter() { - mesh.indices.push(i + voff); + Self { + units_per_em, + glyphs: RwLock::new(glyphs), } } } @@ -157,8 +130,7 @@ impl Font { file_buffer: Vec, ) -> Self { let mut data = FontData::load(face_index, script, direction, vertical, file_buffer); - let mut glyph_cache = GlyphCache::empty(); - data.with_inner_mut(|font| glyph_cache.load_paths(font)); + let glyph_cache = data.with_inner_mut(|font| GlyphCache::new(font)); let data = Mutex::new(data); Self { data, glyph_cache } } @@ -166,6 +138,40 @@ impl Font { pub fn shape(&self, text: &str) -> Vec { self.data.lock().shape(text) } + + pub fn draw(&self, mesh: &mut DummyText, positions: &[GlyphPosition], yoff: f32) { + // TODO defer tessellation of missed glyph cache entries + let mut glyphs = self.glyph_cache.glyphs.write(); + let units_per_em = self.glyph_cache.units_per_em; + let mut xcur = 0; + let mut ycur = 0; + for position in positions.iter() { + let glyph = glyphs.get_mut(position.index as usize).unwrap().get_mesh(); + + let xpos = xcur + position.xoff; + let ypos = ycur + position.yoff; + xcur += position.hori_advance; + ycur += position.vert_advance; + + let voff = mesh.vertices.len() as MeshIndex; + let scale = TEXT_SCALE / units_per_em; + let xpos = xpos as f32 * scale; + let ypos = ypos as f32 * scale; + + for v in glyph.vertices.iter() { + let x = v.position.x + xpos - 0.9; + let y = v.position.y + ypos + yoff; + mesh.vertices.push(MeshVertex { + position: canary_types::Vec2 { x, y }, + color: v.color, + }); + } + + for i in glyph.indices.iter() { + mesh.indices.push(i + voff); + } + } + } } #[self_referencing] @@ -310,20 +316,9 @@ impl Default for DummyText { let line_height = -0.1; let mut line_offset = 0.9; for family in font_families.iter() { - let mut font = store.load_font(family); + let font = store.load_font(family); let glyphs = font.shape(text); - - let mut xcur = 0; - let mut ycur = 0; - for glyph in glyphs.iter() { - let xpos = xcur + glyph.xoff; - let ypos = ycur + glyph.yoff; - xcur += glyph.hori_advance; - ycur += glyph.vert_advance; - font.glyph_cache - .draw(&mut mesh, glyph.index, xpos, ypos, line_offset); - } - + font.draw(&mut mesh, &glyphs, line_offset); line_offset += line_height; }