You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
One of the main features missing is the ability to shape / decode the font once on load - right now the entire crate is riddled with Rc<RefCell<...>>, which makes it impossible to shape words in parallel. I'd like to use this crate for my graphics framework, but shaping words synchronously is very slow. Ideally it should be possible to parse the entire font upfront (even if that takes hundreds of milliseconds) instead of decoding on-the-fly. The gpos::apply() and gsub::apply() functions currently take types like LayoutCache that don't implement Send, so it's not possible to shape words in parallel.
Right now the only thing I can do is to parse the glyf table upfront in parallel:
structParsedFont{glyph_records_decoded:BTreeMap<usize,OwnedGlyph>,}implParsedFont{fnnew(font_bytes:&[u8],font_index:usize) -> Self{let scope = ReadScope::new(font_bytes);let font_file = scope.read::<FontData<'_>>().ok()?;let provider = font_file.table_provider(font_index).ok()?;let glyf_data = provider.table_data(tag::GLYF).ok()??.into_owned();let glyf_table = ReadScope::new(&glyf_data).read_dep::<GlyfTable<'_>>(&loca_table).ok()?;let glyph_records_decoded = glyf_table.records.into_par_iter()// <- decode in parallel.enumerate().filter_map(|(glyph_index,mut glyph_record)| {
glyph_record.parse().ok()?;match glyph_record {GlyfRecord::Empty | GlyfRecord::Present(_) => None,GlyfRecord::Parsed(g) => {Some((glyph_index,OwnedGlyph::from_glyph_data(g)))}}}).collect::<Vec<_>>();ParsedFont{glyph_records_decoded: glyph_records_decoded.into_iter().collect(),}}// this function is now much faster (no need to decode the glyph_record on the fly)pubfnget_glyph_size(&self,glyph_index:u16) -> Option<(i32,i32)>{let g = self.glyph_records_decoded.get(&(glyph_index asusize))?;let glyph_width = g.bounding_box.x_maxasi32 - g.bounding_box.x_minasi32;// widthlet glyph_height = g.bounding_box.y_maxasi32 - g.bounding_box.y_minasi32;// heightSome((glyph_width, glyph_height))}}
The only problem is that I can't do this with font shaping, i.e. this doesn't work:
let shaped_words = words
.par_iter().map(|w| upfront_parsed_font.shape(word.chars[..], script, lang)).collect();
In GUI frameworks it's often necessary to shape characters many times, so it would be nice to decode the kerning / positioning / substitution tables upfront. Right now, font shaping is the heaviest part of the entire layout step (4 out of 5 ms for layout are spent on text shaping alone), so parallelizing text shaping on a per-word basis would be great.
The text was updated successfully, but these errors were encountered:
One of the main features missing is the ability to shape / decode the font once on load - right now the entire crate is riddled with
Rc<RefCell<...>>
, which makes it impossible to shape words in parallel. I'd like to use this crate for my graphics framework, but shaping words synchronously is very slow. Ideally it should be possible to parse the entire font upfront (even if that takes hundreds of milliseconds) instead of decoding on-the-fly. Thegpos::apply()
andgsub::apply()
functions currently take types likeLayoutCache
that don't implementSend
, so it's not possible to shape words in parallel.Right now the only thing I can do is to parse the
glyf
table upfront in parallel:The only problem is that I can't do this with font shaping, i.e. this doesn't work:
In GUI frameworks it's often necessary to shape characters many times, so it would be nice to decode the kerning / positioning / substitution tables upfront. Right now, font shaping is the heaviest part of the entire layout step (4 out of 5 ms for layout are spent on text shaping alone), so parallelizing text shaping on a per-word basis would be great.
The text was updated successfully, but these errors were encountered: