diff --git a/src/binary/read.rs b/src/binary/read.rs index 92a538c0..20375f13 100644 --- a/src/binary/read.rs +++ b/src/binary/read.rs @@ -17,7 +17,7 @@ use std::collections::hash_map::Entry; use std::collections::HashMap; use std::fmt; use std::marker::PhantomData; -use std::rc::Rc; +use std::sync::Arc; #[derive(Debug, Copy, Clone)] pub struct ReadEof {} @@ -60,7 +60,7 @@ pub struct ReadCtxt<'a> { } pub struct ReadCache { - map: HashMap>, + map: HashMap>, } pub trait ReadBinary { @@ -306,16 +306,16 @@ impl<'a> ReadScope<'a> { pub fn read_cache( &self, cache: &mut ReadCache>, - ) -> Result>, ParseError> + ) -> Result>, ParseError> where T: 'static + ReadBinaryDep = ()>, { match cache.map.entry(self.base) { Entry::Vacant(entry) => { - let t = Rc::new(self.read::()?); - Ok(Rc::clone(entry.insert(t))) + let t = Arc::new(self.read::()?); + Ok(Arc::clone(entry.insert(t))) } - Entry::Occupied(entry) => Ok(Rc::clone(entry.get())), + Entry::Occupied(entry) => Ok(Arc::clone(entry.get())), } } @@ -323,17 +323,17 @@ impl<'a> ReadScope<'a> { &self, cache: &mut ReadCache>, state: LayoutCache, - ) -> Result>, ParseError> + ) -> Result>, ParseError> where T: 'static + ReadBinaryDep = LayoutCache
>, Table: LayoutTableType, { match cache.map.entry(self.base) { Entry::Vacant(entry) => { - let t = Rc::new(self.read_dep::(state)?); - Ok(Rc::clone(entry.insert(t))) + let t = Arc::new(self.read_dep::(state)?); + Ok(Arc::clone(entry.insert(t))) } - Entry::Occupied(entry) => Ok(Rc::clone(entry.get())), + Entry::Occupied(entry) => Ok(Arc::clone(entry.get())), } } diff --git a/src/context.rs b/src/context.rs index 9f5fcefb..a0761c08 100644 --- a/src/context.rs +++ b/src/context.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use std::ops::RangeInclusive; -use std::rc::Rc; +use std::sync::Arc; use crate::gdef; use crate::layout::{ClassDef, Coverage, GDEFTable}; @@ -28,8 +28,8 @@ pub struct MatchType { pub enum GlyphTable<'a> { Empty, ById(&'a [u16]), - ByClassDef(Rc, &'a [u16]), - ByCoverage(&'a [Rc]), + ByClassDef(Arc, &'a [u16]), + ByCoverage(&'a [Arc]), } impl GlyphTable<'_> { diff --git a/src/font.rs b/src/font.rs index 14ce9e7a..85271951 100644 --- a/src/font.rs +++ b/src/font.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use std::convert::{self}; -use std::rc::Rc; +use std::sync::Arc; use bitflags::bitflags; use pathfinder_geometry::rect::RectF; @@ -89,23 +89,23 @@ pub struct Font { pub maxp_table: MaxpTable, hmtx_table: Box<[u8]>, pub hhea_table: HheaTable, - vmtx_table: LazyLoad>, - vhea_table: LazyLoad>, + vmtx_table: LazyLoad>, + vhea_table: LazyLoad>, cmap_subtable_offset: usize, pub cmap_subtable_encoding: Encoding, - gdef_cache: LazyLoad>, - morx_cache: LazyLoad>, + gdef_cache: LazyLoad>, + morx_cache: LazyLoad>, gsub_cache: LazyLoad>, gpos_cache: LazyLoad>, - kern_cache: LazyLoad>, + kern_cache: LazyLoad>, os2_us_first_char_index: LazyLoad, glyph_cache: GlyphCache, pub glyph_table_flags: GlyphTableFlags, loca_glyf: LocaGlyf, - cff_cache: LazyLoad>, - cff2_cache: LazyLoad>, + cff_cache: LazyLoad>, + cff2_cache: LazyLoad>, embedded_image_filter: GlyphTableFlags, - embedded_images: LazyLoad>, + embedded_images: LazyLoad>, axis_count: u16, } @@ -403,7 +403,7 @@ impl Font { let opt_gpos_cache = check_set_err(self.gpos_cache(), &mut err); let opt_gdef_table = check_set_err(self.gdef_table(), &mut err); let opt_morx_table = check_set_err(self.morx_table(), &mut err); - let opt_gdef_table = opt_gdef_table.as_ref().map(Rc::as_ref); + let opt_gdef_table = opt_gdef_table.as_ref().map(Arc::as_ref); let opt_kern_table = check_set_err(self.kern_table(), &mut err); let opt_kern_table = opt_kern_table .as_ref() @@ -771,7 +771,7 @@ impl Font { table_builder: |data: &Box<[u8]>| ReadScope::new(data).read::>(), } .try_build()?; - Ok(Some(Rc::new(cff))) + Ok(Some(Arc::new(cff))) })? .ok_or(ParseError::MissingTable(tag::CFF2))?; @@ -796,7 +796,7 @@ impl Font { table_builder: |data: &Box<[u8]>| ReadScope::new(data).read::>(), } .try_build()?; - Ok(Some(Rc::new(cff))) + Ok(Some(Arc::new(cff))) })? .ok_or(ParseError::MissingTable(tag::CFF))?; @@ -978,24 +978,24 @@ impl Font { ) } - fn embedded_images(&mut self) -> Result>, ParseError> { + fn embedded_images(&mut self) -> Result>, ParseError> { let provider = &self.font_table_provider; let num_glyphs = usize::from(self.maxp_table.num_glyphs); let tables_to_check = self.glyph_table_flags & self.embedded_image_filter; self.embedded_images.get_or_load(|| { if tables_to_check.contains(GlyphTableFlags::COLR) { let images = load_colr_cpal(provider).map(Images::Colr)?; - Ok(Some(Rc::new(images))) + Ok(Some(Arc::new(images))) } else if tables_to_check.contains(GlyphTableFlags::SVG) { let images = load_svg(provider).map(Images::Svg)?; - Ok(Some(Rc::new(images))) + Ok(Some(Arc::new(images))) } else if tables_to_check.contains(GlyphTableFlags::CBDT) { let images = load_cblc_cbdt(provider, tag::CBLC, tag::CBDT) .map(|(cblc, cbdt)| Images::Embedded { cblc, cbdt })?; - Ok(Some(Rc::new(images))) + Ok(Some(Arc::new(images))) } else if tables_to_check.contains(GlyphTableFlags::SBIX) { let images = load_sbix(provider, num_glyphs).map(Images::Sbix)?; - Ok(Some(Rc::new(images))) + Ok(Some(Arc::new(images))) } else if tables_to_check.contains(GlyphTableFlags::EBDT) { let images = load_cblc_cbdt(provider, tag::EBLC, tag::EBDT).map(|(eblc, ebdt)| { @@ -1004,7 +1004,7 @@ impl Font { cbdt: ebdt, } })?; - Ok(Some(Rc::new(images))) + Ok(Some(Arc::new(images))) } else { Ok(None) } @@ -1040,7 +1040,7 @@ impl Font { let vmtx = self .vmtx_table .get_or_load(|| { - read_and_box_optional_table(provider, tag::VMTX).map(|ok| ok.map(Rc::from)) + read_and_box_optional_table(provider, tag::VMTX).map(|ok| ok.map(Arc::from)) }) .ok()?; let vhea = self.vhea_table().ok()?; @@ -1056,19 +1056,19 @@ impl Font { load_os2_table(&self.font_table_provider) } - pub fn gdef_table(&mut self) -> Result>, ParseError> { + pub fn gdef_table(&mut self) -> Result>, ParseError> { let provider = &self.font_table_provider; self.gdef_cache.get_or_load(|| { if let Some(gdef_data) = provider.table_data(tag::GDEF)? { let gdef = ReadScope::new(&gdef_data).read::()?; - Ok(Some(Rc::new(gdef))) + Ok(Some(Arc::new(gdef))) } else { Ok(None) } }) } - pub fn morx_table(&mut self) -> Result>, ParseError> { + pub fn morx_table(&mut self) -> Result>, ParseError> { let provider = &self.font_table_provider; let num_glyphs = self.num_glyphs(); self.morx_cache.get_or_load(|| { @@ -1076,7 +1076,7 @@ impl Font { let morx = tables::Morx::try_new(morx_data.into(), |data| { ReadScope::new(data).read_dep::>(num_glyphs) })?; - Ok(Some(Rc::new(morx))) + Ok(Some(Arc::new(morx))) } else { Ok(None) } @@ -1109,12 +1109,12 @@ impl Font { }) } - pub fn kern_table(&mut self) -> Result>, ParseError> { + pub fn kern_table(&mut self) -> Result>, ParseError> { let provider = &self.font_table_provider; self.kern_cache.get_or_load(|| { if let Some(kern_data) = provider.table_data(tag::KERN)? { match ReadScope::new(&kern_data).read::>() { - Ok(kern) => Ok(Some(Rc::new(kern.to_owned()))), + Ok(kern) => Ok(Some(Arc::new(kern.to_owned()))), // This error may be encountered because there is a kern 1.0 version defined by // Apple that is not in the OpenType spec. It only works on macOS. We don't // support it so return None instead of returning an error. @@ -1127,12 +1127,12 @@ impl Font { }) } - pub fn vhea_table(&mut self) -> Result>, ParseError> { + pub fn vhea_table(&mut self) -> Result>, ParseError> { let provider = &self.font_table_provider; self.vhea_table.get_or_load(|| { if let Some(vhea_data) = provider.table_data(tag::VHEA)? { let vhea = ReadScope::new(&vhea_data).read::()?; - Ok(Some(Rc::new(vhea))) + Ok(Some(Arc::new(vhea))) } else { Ok(None) } diff --git a/src/glyph_info.rs b/src/glyph_info.rs index cef9cbbe..f15e3725 100644 --- a/src/glyph_info.rs +++ b/src/glyph_info.rs @@ -4,7 +4,7 @@ use std::borrow::Cow; use std::collections::HashMap; -use std::rc::Rc; +use std::sync::Arc; use ouroboros::self_referencing; use rustc_hash::FxHashMap; @@ -127,16 +127,16 @@ fn unique_glyph_names<'a>( let mut seen = FxHashMap::with_capacity_and_hasher(capacity, Default::default()); let mut unique_names = Vec::with_capacity(capacity); - for name in names.map(Rc::new) { + for name in names.map(Arc::new) { let alt = *seen - .entry(Rc::clone(&name)) + .entry(Arc::clone(&name)) .and_modify(|alt| *alt += 1) .or_insert(0); let unique_name = if alt == 0 { name } else { // name is not unique, generate a new name for it - Rc::new(Cow::from(format!("{}.alt{:02}", name, alt))) + Arc::new(Cow::from(format!("{}.alt{:02}", name, alt))) }; unique_names.push(unique_name) @@ -147,7 +147,7 @@ fn unique_glyph_names<'a>( // to name and it's been dropped. unique_names .into_iter() - .map(|name| Rc::try_unwrap(name).unwrap()) + .map(|name| Arc::try_unwrap(name).unwrap()) .collect() } diff --git a/src/gsub.rs b/src/gsub.rs index 0696817d..be1ee8da 100644 --- a/src/gsub.rs +++ b/src/gsub.rs @@ -916,7 +916,8 @@ fn get_supported_features( ) -> Result { let feature_mask = match gsub_cache .supported_features - .borrow_mut() + .lock() + .unwrap() .entry((script_tag, lang_tag_key(opt_lang_tag))) { Entry::Occupied(entry) => FeatureMask::from_bits_truncate(*entry.get()), @@ -962,7 +963,7 @@ fn find_alternate(features_list: &[FeatureInfo], feature_tag: u32) -> Option Option>, feature_mask: FeatureMask, ) -> Result { - let index = match gsub_cache.lookups_index.borrow_mut().entry(( + let index = match gsub_cache.lookups_index.lock().unwrap().entry(( script_tag, lang_tag_key(opt_lang_tag), feature_mask.bits(), @@ -1426,8 +1427,9 @@ pub fn get_lookups_cache_index( feature_mask, feature_variations, )?; - let index = gsub_cache.cached_lookups.borrow().len(); - gsub_cache.cached_lookups.borrow_mut().push(lookups); + let mut cached_lookups = gsub_cache.cached_lookups.lock().unwrap(); + let index = cached_lookups.len(); + cached_lookups.push(lookups); *entry.insert(index) } else { *entry.insert(0) @@ -1552,8 +1554,9 @@ fn gsub_apply_default( feature_variations, feature_mask, )?; - let lookups = &gsub_cache.cached_lookups.borrow()[index]; - let lookups_frac = &gsub_cache.cached_lookups.borrow()[index_frac]; + let cached_lookups = gsub_cache.cached_lookups.lock().unwrap(); + let lookups = &cached_lookups[index]; + let lookups_frac = &cached_lookups[index_frac]; gsub_apply_lookups_frac( gsub_cache, gsub_table, @@ -1570,7 +1573,7 @@ fn gsub_apply_default( feature_variations, feature_mask, )?; - let lookups = &gsub_cache.cached_lookups.borrow()[index]; + let lookups = &gsub_cache.cached_lookups.lock().unwrap()[index]; gsub_apply_lookups(gsub_cache, gsub_table, opt_gdef_table, lookups, glyphs)?; } } @@ -1718,7 +1721,7 @@ fn apply_rvrn( feature_variations, FeatureMask::RVRN, )?; - let lookups = &gsub_cache.cached_lookups.borrow()[index]; + let lookups = &gsub_cache.cached_lookups.lock().unwrap()[index]; gsub_apply_lookups(gsub_cache, gsub_table, opt_gdef_table, lookups, glyphs)?; Ok(()) } diff --git a/src/layout.rs b/src/layout.rs index 8f0b16f0..3fc966d0 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -3,11 +3,11 @@ pub mod morx; use std::borrow::Cow; -use std::cell::RefCell; use std::collections::HashMap; use std::marker::PhantomData; use std::ops::RangeInclusive; -use std::rc::Rc; +use std::sync::Arc; +use std::sync::Mutex; use log::warn; @@ -1025,18 +1025,19 @@ impl LookupList { &self, cache: &LayoutCache, lookup_index: usize, - ) -> Result>, ParseError> { - let lookup_vec = &mut cache.lookup_cache.borrow_mut(); + ) -> Result>, ParseError> { + if let Some(Some(cached)) = cache.lookup_cache.lock().unwrap().get(lookup_index) { + return Ok(Arc::clone(cached)); + } + + let lookup_cache_item = Arc::new(self.read_lookup_gsub(cache, lookup_index)?); + let mut lookup_vec = cache.lookup_cache.lock().unwrap(); if lookup_index >= lookup_vec.len() { lookup_vec.resize(lookup_index + 1, None); } - if let Some(ref lookup_cache_item) = lookup_vec[lookup_index] { - Ok(Rc::clone(lookup_cache_item)) - } else { - let lookup_cache_item = Rc::new(self.read_lookup_gsub(cache, lookup_index)?); - lookup_vec[lookup_index] = Some(Rc::clone(&lookup_cache_item)); - Ok(lookup_cache_item) - } + Ok(Arc::clone( + lookup_vec[lookup_index].get_or_insert(lookup_cache_item), + )) } fn read_lookup_gsub( @@ -1083,18 +1084,19 @@ impl LookupList { &self, cache: &LayoutCache, lookup_index: usize, - ) -> Result>, ParseError> { - let lookup_vec = &mut cache.lookup_cache.borrow_mut(); + ) -> Result>, ParseError> { + if let Some(Some(cached)) = cache.lookup_cache.lock().unwrap().get(lookup_index) { + return Ok(Arc::clone(cached)); + } + + let lookup_cache_item = Arc::new(self.read_lookup_gpos(cache, lookup_index)?); + let mut lookup_vec = cache.lookup_cache.lock().unwrap(); if lookup_index >= lookup_vec.len() { lookup_vec.resize(lookup_index + 1, None); } - if let Some(ref lookup_cache_item) = lookup_vec[lookup_index] { - Ok(Rc::clone(lookup_cache_item)) - } else { - let lookup_cache_item = Rc::new(self.read_lookup_gpos(cache, lookup_index)?); - lookup_vec[lookup_index] = Some(Rc::clone(&lookup_cache_item)); - Ok(lookup_cache_item) - } + Ok(Arc::clone( + lookup_vec[lookup_index].get_or_insert(lookup_cache_item), + )) } fn read_lookup_gpos( @@ -1366,11 +1368,11 @@ impl LayoutTableType for GPOS { pub enum SingleSubst { Format1 { - coverage: Rc, + coverage: Arc, delta_glyph_index: i16, }, Format2 { - coverage: Rc, + coverage: Arc, substitute_glyph_array: Vec, }, } @@ -1386,7 +1388,7 @@ impl ReadBinaryDep for SingleSubst { let coverage_offset = usize::from(ctxt.read_u16be()?); let coverage = subtable .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let delta_glyph_index = ctxt.read_i16be()?; Ok(SingleSubst::Format1 { coverage, @@ -1397,7 +1399,7 @@ impl ReadBinaryDep for SingleSubst { let coverage_offset = usize::from(ctxt.read_u16be()?); let coverage = subtable .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let glyph_count = ctxt.read_u16be()?; let substitute_glyph_array = ctxt.read_array::(usize::from(glyph_count))?.to_vec(); @@ -1443,7 +1445,7 @@ impl SingleSubst { } pub struct MultipleSubst { - coverage: Rc, + coverage: Arc, sequences: Vec, } @@ -1462,7 +1464,7 @@ impl ReadBinaryDep for MultipleSubst { let coverage_offset = usize::from(ctxt.read_u16be()?); let coverage = scope .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let sequence_count = usize::from(ctxt.read_u16be()?); let sequence_offsets = ctxt.read_array::(sequence_count)?; let sequences = read_objects::(&scope, sequence_offsets)?; @@ -1503,7 +1505,7 @@ impl ReadBinary for SequenceTable { } pub struct AlternateSubst { - coverage: Rc, + coverage: Arc, alternatesets: Vec, } @@ -1522,7 +1524,7 @@ impl ReadBinaryDep for AlternateSubst { let coverage_offset = usize::from(ctxt.read_u16be()?); let coverage = scope .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let alternateset_count = usize::from(ctxt.read_u16be()?); let alternateset_offsets = ctxt.read_array::(alternateset_count)?; let alternatesets = read_objects::(&scope, alternateset_offsets)?; @@ -1562,7 +1564,7 @@ impl ReadBinary for AlternateSet { } pub struct LigatureSubst { - coverage: Rc, + coverage: Arc, ligaturesets: Vec, } @@ -1587,7 +1589,7 @@ impl ReadBinaryDep for LigatureSubst { let coverage_offset = usize::from(ctxt.read_u16be()?); let coverage = scope .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let ligatureset_count = usize::from(ctxt.read_u16be()?); let ligatureset_offsets = ctxt.read_array::(ligatureset_count)?; let ligaturesets = read_objects::(&scope, ligatureset_offsets)?; @@ -1857,11 +1859,11 @@ impl ReadBinary for Anchor { pub enum SinglePos { Format1 { - coverage: Rc, + coverage: Arc, value_record: ValueRecord, }, Format2 { - coverage: Rc, + coverage: Arc, value_records: Vec, }, } @@ -1878,7 +1880,7 @@ impl ReadBinaryDep for SinglePos { let coverage_offset = usize::from(ctxt.read_u16be()?); let coverage = scope .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let value_format = ctxt.read::()?; let value_record = ctxt.read_dep::((scope, value_format))?; Ok(SinglePos::Format1 { @@ -1890,7 +1892,7 @@ impl ReadBinaryDep for SinglePos { let coverage_offset = usize::from(ctxt.read_u16be()?); let coverage = scope .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let value_format = ctxt.read::()?; let value_count = usize::from(ctxt.read_u16be()?); let value_records = ctxt @@ -1937,13 +1939,13 @@ impl SinglePos { pub enum PairPos { Format1 { - coverage: Rc, + coverage: Arc, pairsets: Vec, }, Format2 { - coverage: Rc, - classdef1: Rc, - classdef2: Rc, + coverage: Arc, + classdef1: Arc, + classdef2: Arc, class2_count: usize, class1_records: Vec, }, @@ -1961,7 +1963,7 @@ impl ReadBinaryDep for PairPos { let coverage_offset = usize::from(ctxt.read_u16be()?); let coverage = scope .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let value_format1 = ctxt.read::()?; let value_format2 = ctxt.read::()?; let pairset_count = usize::from(ctxt.read_u16be()?); @@ -1977,17 +1979,17 @@ impl ReadBinaryDep for PairPos { let coverage_offset = usize::from(ctxt.read_u16be()?); let coverage = scope .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let value_format1 = ctxt.read::()?; let value_format2 = ctxt.read::()?; let classdef1_offset = usize::from(ctxt.read_u16be()?); let classdef2_offset = usize::from(ctxt.read_u16be()?); let classdef1 = scope .offset(classdef1_offset) - .read_cache::(&mut cache.classdefs.borrow_mut())?; + .read_cache::(&mut cache.classdefs.lock().unwrap())?; let classdef2 = scope .offset(classdef2_offset) - .read_cache::(&mut cache.classdefs.borrow_mut())?; + .read_cache::(&mut cache.classdefs.lock().unwrap())?; let class1_count = usize::from(ctxt.read_u16be()?); let class2_count = usize::from(ctxt.read_u16be()?); let class1_records = ctxt @@ -2165,7 +2167,7 @@ impl PairPos { } pub struct CursivePos { - coverage: Rc, + coverage: Arc, entry_exit_records: Vec, } @@ -2181,7 +2183,7 @@ impl ReadBinaryDep for CursivePos { let coverage_offset = usize::from(ctxt.read_u16be()?); let coverage = scope .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let entry_exit_count = usize::from(ctxt.read_u16be()?); let entry_exit_records = ctxt .read_array_dep::(entry_exit_count, scope)? @@ -2269,8 +2271,8 @@ impl CursivePos { // also used for MarkToMark tables pub struct MarkBasePos { - mark_coverage: Rc, - base_coverage: Rc, + mark_coverage: Arc, + base_coverage: Arc, mark_class_count: usize, mark_array: MarkArray, base_array: BaseArray, @@ -2292,10 +2294,10 @@ impl ReadBinaryDep for MarkBasePos { let base_array_offset = usize::from(ctxt.read_u16be()?); let mark_coverage = scope .offset(mark_coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let base_coverage = scope .offset(base_coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let mark_array = scope.offset(mark_array_offset).read::()?; let base_array = scope .offset(base_array_offset) @@ -2437,8 +2439,8 @@ impl MarkBasePos { } pub struct MarkLigPos { - mark_coverage: Rc, - liga_coverage: Rc, + mark_coverage: Arc, + liga_coverage: Arc, mark_class_count: usize, mark_array: MarkArray, ligature_array: LigatureArray, @@ -2459,10 +2461,10 @@ impl ReadBinaryDep for MarkLigPos { let liga_array_offset = usize::from(ctxt.read_u16be()?); let mark_coverage = scope .offset(mark_coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let liga_coverage = scope .offset(liga_coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let mark_array = scope.offset(mark_array_offset).read::()?; let ligature_array = scope .offset(liga_array_offset) @@ -2586,18 +2588,18 @@ impl MarkLigPos { pub enum ContextLookup { Format1 { - coverage: Rc, + coverage: Arc, subrulesets: Vec>, phantom: PhantomData, }, Format2 { - coverage: Rc, - classdef: Rc, + coverage: Arc, + classdef: Arc, subclasssets: Vec>, phantom: PhantomData, }, Format3 { - coverages: Vec>, + coverages: Vec>, lookup_records: Vec<(u16, u16)>, phantom: PhantomData, }, @@ -2623,22 +2625,22 @@ pub struct SubClassRule { pub enum ChainContextLookup { Format1 { - coverage: Rc, + coverage: Arc, chainsubrulesets: Vec>, phantom: PhantomData, }, Format2 { - coverage: Rc, - backtrack_classdef: Rc, - input_classdef: Rc, - lookahead_classdef: Rc, + coverage: Arc, + backtrack_classdef: Arc, + input_classdef: Arc, + lookahead_classdef: Arc, chainsubclasssets: Vec>, phantom: PhantomData, }, Format3 { - backtrack_coverages: Vec>, - input_coverages: Vec>, - lookahead_coverages: Vec>, + backtrack_coverages: Vec>, + input_coverages: Vec>, + lookahead_coverages: Vec>, lookup_records: Vec<(u16, u16)>, phantom: PhantomData, }, @@ -2680,7 +2682,7 @@ impl ReadBinaryDep for ContextLookup { let subrulesets = read_objects_nullable::(&scope, subruleset_offsets)?; let coverage = scope .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; Ok(ContextLookup::Format1 { coverage, subrulesets, @@ -2697,10 +2699,10 @@ impl ReadBinaryDep for ContextLookup { read_objects_nullable::(&scope, subclassset_offsets)?; let coverage = scope .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let classdef = scope .offset(classdef_offset) - .read_cache::(&mut cache.classdefs.borrow_mut())?; + .read_cache::(&mut cache.classdefs.lock().unwrap())?; Ok(ContextLookup::Format2 { coverage, classdef, @@ -2731,11 +2733,11 @@ pub enum ReverseChainSingleSubst { /// Format 1 Format1 { /// Coverage table for the single input glyph - coverage: Rc, + coverage: Arc, /// Array of backtrack sequence coverages, ordered by glyph sequence - backtrack_coverages: Vec>, + backtrack_coverages: Vec>, /// Array of lookahead sequence coverages, ordered by glyph sequence - lookahead_coverages: Vec>, + lookahead_coverages: Vec>, /// Array of substitute glyphs, ordered by coverage index substitute_glyphs: Vec, }, @@ -2759,7 +2761,7 @@ impl ReadBinaryDep for ReverseChainSingleSubst { let substitute_glyphs = ctxt.read_array::(glyph_count)?.to_vec(); let coverage = scope .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let backtrack_coverages = read_coverages(&scope, cache, backtrack_coverage_offsets)?; let lookahead_coverages = @@ -2823,12 +2825,12 @@ fn read_coverages<'a, T: LayoutTableType>( scope: &ReadScope<'a>, cache: &LayoutCache, offsets: ReadArray<'a, U16Be>, -) -> Result>, ParseError> { +) -> Result>, ParseError> { let mut coverages = Vec::with_capacity(offsets.len()); for coverage_offset in &offsets { let coverage = scope .offset(usize::from(coverage_offset)) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; coverages.push(coverage); } Ok(coverages) @@ -2906,7 +2908,7 @@ impl ReadBinaryDep for ChainContextLookup { read_objects_nullable::(&scope, chainsubruleset_offsets)?; let coverage = scope .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; Ok(ChainContextLookup::Format1 { coverage, chainsubrulesets, @@ -2925,16 +2927,16 @@ impl ReadBinaryDep for ChainContextLookup { read_objects_nullable::(&scope, chainsubclassset_offsets)?; let coverage = scope .offset(coverage_offset) - .read_cache::(&mut cache.coverages.borrow_mut())?; + .read_cache::(&mut cache.coverages.lock().unwrap())?; let backtrack_classdef = scope .offset(backtrack_classdef_offset) - .read_cache::(&mut cache.classdefs.borrow_mut())?; + .read_cache::(&mut cache.classdefs.lock().unwrap())?; let input_classdef = scope .offset(input_classdef_offset) - .read_cache::(&mut cache.classdefs.borrow_mut())?; + .read_cache::(&mut cache.classdefs.lock().unwrap())?; let lookahead_classdef = scope .offset(lookahead_classdef_offset) - .read_cache::(&mut cache.classdefs.borrow_mut())?; + .read_cache::(&mut cache.classdefs.lock().unwrap())?; Ok(ChainContextLookup::Format2 { coverage, backtrack_classdef, @@ -3092,7 +3094,7 @@ pub fn context_lookup_info<'a, T, Table: LayoutTableType>( let match_context = MatchContext { backtrack_table: GlyphTable::Empty, input_table: GlyphTable::ByClassDef( - Rc::clone(classdef), + Arc::clone(classdef), &subclassrule.input_sequence, ), lookahead_table: GlyphTable::Empty, @@ -3195,15 +3197,15 @@ pub fn chain_context_lookup_info<'a, T, Table: LayoutTableType>( for chainsubclassrule in &chainsubclassset.chainsubclassrules { let match_context = MatchContext { backtrack_table: GlyphTable::ByClassDef( - Rc::clone(backtrack_classdef), + Arc::clone(backtrack_classdef), &chainsubclassrule.backtrack_sequence, ), input_table: GlyphTable::ByClassDef( - Rc::clone(input_classdef), + Arc::clone(input_classdef), &chainsubclassrule.input_sequence, ), lookahead_table: GlyphTable::ByClassDef( - Rc::clone(lookahead_classdef), + Arc::clone(lookahead_classdef), &chainsubclassrule.lookahead_sequence, ), }; @@ -3508,9 +3510,9 @@ impl ReadBinary for MarkGlyphSets { } } -pub type LayoutCache = Rc>; +pub type LayoutCache = Arc>; -pub type LookupCache = Vec>>>; +pub type LookupCache = Vec>>>; pub struct LookupCacheItem { pub lookup_flag: LookupFlag, @@ -3520,28 +3522,28 @@ pub struct LookupCacheItem { pub struct LayoutCacheData { pub layout_table: LayoutTable, - coverages: RefCell>, - classdefs: RefCell>, - lookup_cache: RefCell>, + coverages: Mutex>, + classdefs: Mutex>, + lookup_cache: Mutex>, /// maps (script_tag, opt_lang_tag) to FeatureMask /// opt_lang_tag = None is represented as `DFLT` - pub supported_features: RefCell>, + pub supported_features: Mutex>, /// maps (script_tag, lang_tag, FeatureMask) to cached_lookups index - pub lookups_index: RefCell>, + pub lookups_index: Mutex>, - pub cached_lookups: RefCell>>, + pub cached_lookups: Mutex>>, } pub fn new_layout_cache(layout_table: LayoutTable) -> LayoutCache { - let coverages = RefCell::new(ReadCache::new()); - let classdefs = RefCell::new(ReadCache::new()); - let lookup_cache = RefCell::new(Vec::new()); - let supported_features = RefCell::new(HashMap::new()); - let lookups_index = RefCell::new(HashMap::new()); - let cached_lookups = RefCell::new(vec![Vec::new()]); - Rc::new(LayoutCacheData { + let coverages = Mutex::new(ReadCache::new()); + let classdefs = Mutex::new(ReadCache::new()); + let lookup_cache = Mutex::new(Vec::new()); + let supported_features = Mutex::new(HashMap::new()); + let lookups_index = Mutex::new(HashMap::new()); + let cached_lookups = Mutex::new(vec![Vec::new()]); + Arc::new(LayoutCacheData { layout_table, coverages, classdefs, diff --git a/src/scripts/arabic.rs b/src/scripts/arabic.rs index dd93d358..d111e3af 100644 --- a/src/scripts/arabic.rs +++ b/src/scripts/arabic.rs @@ -236,7 +236,7 @@ fn apply_lookups( feature_variations, feature_mask, )?; - let lookups = &gsub_cache.cached_lookups.borrow()[index]; + let lookups = &gsub_cache.cached_lookups.lock().unwrap()[index]; for &(lookup_index, feature_tag) in lookups { gsub::gsub_apply_lookup( diff --git a/src/scripts/indic.rs b/src/scripts/indic.rs index f84caef0..196de110 100644 --- a/src/scripts/indic.rs +++ b/src/scripts/indic.rs @@ -1894,7 +1894,7 @@ fn apply_basic_features( ) -> Result<(), ParseError> { for feature in BasicFeature::ALL { let index = shaping_data.get_lookups_cache_index(feature.mask())?; - let lookups = &shaping_data.gsub_cache.cached_lookups.borrow()[index]; + let lookups = &shaping_data.gsub_cache.cached_lookups.lock().unwrap()[index]; for &(lookup_index, feature_tag) in lookups { shaping_data.apply_lookup(lookup_index, feature_tag, glyphs, |g| { @@ -2203,7 +2203,7 @@ fn apply_presentation_features( } } let index = shaping_data.get_lookups_cache_index(features)?; - let lookups = &shaping_data.gsub_cache.cached_lookups.borrow()[index]; + let lookups = &shaping_data.gsub_cache.cached_lookups.lock().unwrap()[index]; for &(lookup_index, feature_tag) in lookups { shaping_data.apply_lookup(lookup_index, feature_tag, glyphs, |g| { diff --git a/src/scripts/khmer.rs b/src/scripts/khmer.rs index 8d16c57c..1cf99cdd 100644 --- a/src/scripts/khmer.rs +++ b/src/scripts/khmer.rs @@ -515,7 +515,7 @@ fn apply_basic_features( feature_variations, features, )?; - let lookups = &gsub_cache.cached_lookups.borrow()[index]; + let lookups = &gsub_cache.cached_lookups.lock().unwrap()[index]; for &(lookup_index, feature_tag) in lookups { let feature = match feature_tag { @@ -569,7 +569,7 @@ fn apply_remaining_features( feature_variations, features, )?; - let lookups = &gsub_cache.cached_lookups.borrow()[index]; + let lookups = &gsub_cache.cached_lookups.lock().unwrap()[index]; for &(lookup_index, feature_tag) in lookups { gsub::gsub_apply_lookup( diff --git a/src/scripts/myanmar.rs b/src/scripts/myanmar.rs index 1b1ef4e5..668739c9 100644 --- a/src/scripts/myanmar.rs +++ b/src/scripts/myanmar.rs @@ -896,7 +896,7 @@ fn apply_basic_features( ) -> Result<(), ParseError> { for feature in BasicFeature::ALL { let index = shaping_data.get_lookups_cache_index(feature.mask())?; - let lookups = &shaping_data.gsub_cache.cached_lookups.borrow()[index]; + let lookups = &shaping_data.gsub_cache.cached_lookups.lock().unwrap()[index]; for &(lookup_index, feature_tag) in lookups { shaping_data.apply_lookup(lookup_index, feature_tag, glyphs, |g| { @@ -928,7 +928,7 @@ fn apply_presentation_features( | FeatureMask::RLIG; let index = shaping_data.get_lookups_cache_index(features)?; - let lookups = &shaping_data.gsub_cache.cached_lookups.borrow()[index]; + let lookups = &shaping_data.gsub_cache.cached_lookups.lock().unwrap()[index]; for &(lookup_index, feature_tag) in lookups { shaping_data.apply_lookup(lookup_index, feature_tag, glyphs, |_g| true)?; diff --git a/src/scripts/syriac.rs b/src/scripts/syriac.rs index 0b15fb24..c90a6293 100644 --- a/src/scripts/syriac.rs +++ b/src/scripts/syriac.rs @@ -272,7 +272,7 @@ fn apply_lookups( feature_variations, feature_mask, )?; - let lookups = &gsub_cache.cached_lookups.borrow()[index]; + let lookups = &gsub_cache.cached_lookups.lock().unwrap()[index]; for &(lookup_index, feature_tag) in lookups { gsub::gsub_apply_lookup( diff --git a/src/scripts/thai_lao.rs b/src/scripts/thai_lao.rs index 4fac2a0b..79bb5ba2 100644 --- a/src/scripts/thai_lao.rs +++ b/src/scripts/thai_lao.rs @@ -73,7 +73,7 @@ pub fn gsub_apply_thai_lao( feature_variations, FeatureMask::default(), )?; - let lookups = &gsub_cache.cached_lookups.borrow()[index]; + let lookups = &gsub_cache.cached_lookups.lock().unwrap()[index]; for &(lookup_index, feature_tag) in lookups { gsub::gsub_apply_lookup( diff --git a/src/tables/glyf.rs b/src/tables/glyf.rs index 641062c7..e62964c1 100644 --- a/src/tables/glyf.rs +++ b/src/tables/glyf.rs @@ -11,7 +11,7 @@ mod outline; mod subset; mod variation; -use std::rc::Rc; +use std::sync::Arc; use std::{iter, mem}; use bitflags::bitflags; @@ -142,7 +142,7 @@ pub struct LocaGlyf { /// Raw `glyf` table data. glyf: Box<[u8]>, /// Cache of parsed glyphs indexed by glyph ID. - cache: FxHashMap>, + cache: FxHashMap>, } /// A record from the `glyf` table that maybe parsed @@ -1076,9 +1076,9 @@ impl LocaGlyf { } /// Look up the glyph at the supplied index - pub fn glyph(&mut self, index: u16) -> Result, ParseError> { + pub fn glyph(&mut self, index: u16) -> Result, ParseError> { if let Some(glyph) = self.cache.get(&index) { - return Ok(Rc::clone(glyph)); + return Ok(Arc::clone(glyph)); } // Get the start and end offsets for the glyph @@ -1112,11 +1112,11 @@ impl LocaGlyf { // If the slice is empty, then this is a valid, but empty glyph let glyph = if glyph_data.is_empty() { - Rc::new(Glyph::empty()) + Arc::new(Glyph::empty()) } else { - ReadScope::new(glyph_data).read::().map(Rc::new)? + ReadScope::new(glyph_data).read::().map(Arc::new)? }; - self.cache.insert(index, Rc::clone(&glyph)); + self.cache.insert(index, Arc::clone(&glyph)); Ok(glyph) } } diff --git a/src/tables/kern.rs b/src/tables/kern.rs index 782b16be..56ee0b84 100644 --- a/src/tables/kern.rs +++ b/src/tables/kern.rs @@ -341,6 +341,15 @@ impl<'a> KernTable<'a> { }) } + /// Reverse of to_owned, creates a borrowed kerning table from an owned version + pub fn from_owned(kern: &'a owned::KernTable) -> Self { + Self { + version: kern.version, + table_count: kern.table_count, + data: &kern.data[..], + } + } + /// Create an owned version of this `kern` table. pub fn to_owned(&self) -> owned::KernTable { owned::KernTable { diff --git a/tests/aots.rs b/tests/aots.rs index 34e5cb5c..774f586f 100644 --- a/tests/aots.rs +++ b/tests/aots.rs @@ -213,7 +213,7 @@ fn gpos_test( } // Apply GPOS - // Rc>> LayoutCache; + // Arc>> LayoutCache; let cache = new_layout_cache(gpos_table); let script = cache .layout_table diff --git a/tests/arabic.rs b/tests/arabic.rs index fac393cd..cc7b76f7 100644 --- a/tests/arabic.rs +++ b/tests/arabic.rs @@ -14,7 +14,7 @@ mod arabic_tests { use allsorts::tables::OpenTypeFont; use allsorts::tag; use allsorts::Font; - use std::rc::Rc; + use std::sync::Arc; #[test] fn no_gsub_change() { @@ -503,7 +503,7 @@ mod arabic_tests { font.gdef_table() .expect("Error getting GDEF table") .as_ref() - .map(Rc::as_ref), + .map(Arc::as_ref), script_tag, lang_tag, None, diff --git a/tests/indic.rs b/tests/indic.rs index 8955c55d..6310fe34 100644 --- a/tests/indic.rs +++ b/tests/indic.rs @@ -2,7 +2,7 @@ mod common; mod shape; use std::path::Path; -use std::rc::Rc; +use std::sync::Arc; use allsorts::binary::read::ReadScope; use allsorts::error::ShapingError; @@ -70,7 +70,7 @@ fn shape_ttf_indic<'a, T: FontTableProvider>( gsub::apply( dotted_circle_index, &gsub_cache, - gdef_table.as_ref().map(Rc::as_ref), + gdef_table.as_ref().map(Arc::as_ref), script_tag, opt_lang_tag, &Features::Mask(FeatureMask::default()), diff --git a/tests/khmer.rs b/tests/khmer.rs index c5ee5ecf..c5d5ecef 100644 --- a/tests/khmer.rs +++ b/tests/khmer.rs @@ -2,7 +2,7 @@ mod common; mod shape; use std::path::Path; -use std::rc::Rc; +use std::sync::Arc; use allsorts::binary::read::ReadScope; use allsorts::error::ShapingError; @@ -63,7 +63,7 @@ fn shape_ttf_khmer<'a, T: FontTableProvider>( gsub::apply( dotted_circle_index, &gsub_cache, - gdef_table.as_ref().map(Rc::as_ref), + gdef_table.as_ref().map(Arc::as_ref), script_tag, lang_tag, &Features::Mask(FeatureMask::default()), diff --git a/tests/myanmar.rs b/tests/myanmar.rs index c7a911dd..be0d4a02 100644 --- a/tests/myanmar.rs +++ b/tests/myanmar.rs @@ -2,7 +2,7 @@ mod common; mod shape; use std::path::Path; -use std::rc::Rc; +use std::sync::Arc; use allsorts::binary::read::ReadScope; use allsorts::error::ShapingError; @@ -63,7 +63,7 @@ fn shape_ttf_myanmar<'a, T: FontTableProvider>( gsub::apply( dotted_circle_index, &gsub_cache, - gdef_table.as_ref().map(Rc::as_ref), + gdef_table.as_ref().map(Arc::as_ref), script_tag, lang_tag, &Features::Mask(FeatureMask::default()), diff --git a/tests/opentype.rs b/tests/opentype.rs index 95cfd051..73ed4c41 100644 --- a/tests/opentype.rs +++ b/tests/opentype.rs @@ -2,7 +2,7 @@ mod common; mod shape; use std::path::Path; -use std::rc::Rc; +use std::sync::Arc; use allsorts::binary::read::ReadScope; use allsorts::error::ShapingError; @@ -235,7 +235,7 @@ fn shape<'a, T: FontTableProvider>( gsub::apply( dotted_circle_index, &gsub_cache, - gdef_table.as_ref().map(Rc::as_ref), + gdef_table.as_ref().map(Arc::as_ref), script_tag, opt_lang_tag, &Features::Mask(FeatureMask::default()), diff --git a/tests/syriac.rs b/tests/syriac.rs index 0fce6635..1d287df3 100644 --- a/tests/syriac.rs +++ b/tests/syriac.rs @@ -13,7 +13,7 @@ mod syriac_tests { use allsorts::tables::OpenTypeFont; use allsorts::tag; use allsorts::Font; - use std::rc::Rc; + use std::sync::Arc; #[test] fn no_gsub_change() { @@ -490,7 +490,7 @@ mod syriac_tests { font.gdef_table() .expect("Error getting GDEF table") .as_ref() - .map(Rc::as_ref), + .map(Arc::as_ref), tag::SYRC, None, None, diff --git a/tests/thai_lao.rs b/tests/thai_lao.rs index e0a69085..7d649b1f 100644 --- a/tests/thai_lao.rs +++ b/tests/thai_lao.rs @@ -2,7 +2,7 @@ mod common; mod shape; use std::path::Path; -use std::rc::Rc; +use std::sync::Arc; use allsorts::binary::read::ReadScope; use allsorts::gsub::{self, FeatureMask, Features}; @@ -49,7 +49,7 @@ fn test(script_tag: &str, lang_tag: &str, font_path: &str, text: &str, expected: gsub::apply( dotted_circle_index, &gsub_cache, - gdef_table.as_ref().map(Rc::as_ref), + gdef_table.as_ref().map(Arc::as_ref), script_tag, lang_tag, &Features::Mask(FeatureMask::default()),