GlyphCache mutex-locking + Font interior mutability

This commit is contained in:
marceline-cramer 2022-07-18 16:03:02 -06:00
parent 7e15a2f6a8
commit 6b78d51e64
1 changed files with 46 additions and 51 deletions

View File

@ -19,23 +19,14 @@ const TEXT_SCALE: f32 = 0.075;
pub struct GlyphCache {
units_per_em: f32,
glyphs: Vec<CachedGlyph>,
glyphs: RwLock<Vec<CachedGlyph>>,
}
impl GlyphCache {
pub fn empty() -> Self {
Self {
units_per_em: 0.0,
glyphs: Vec::new(),
}
}
pub fn load_paths(&mut self, font: &AllsortsFont<DynamicFontTableProvider>) {
pub fn new(font: &AllsortsFont<DynamicFontTableProvider>) -> 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::<CFF<'_>>().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<u8>,
) -> 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<GlyphPosition> {
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;
}