GlyphCache mutex-locking + Font interior mutability
This commit is contained in:
parent
7e15a2f6a8
commit
6b78d51e64
97
src/text.rs
97
src/text.rs
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue