diff --git a/src/font.rs b/src/font.rs index 48d707c..222fd79 100644 --- a/src/font.rs +++ b/src/font.rs @@ -63,8 +63,8 @@ pub enum MatchingPresentation { struct GlyphCache(Option<(u16, VariationSelector)>); /// Core type for loading a font in order to perform glyph mapping and font shaping. -pub struct Font { - pub font_table_provider: T, +pub struct Font<'a> { + pub font_table_provider: Box, cmap_table: Box<[u8]>, pub maxp_table: MaxpTable, hmtx_table: Box<[u8]>, @@ -149,19 +149,23 @@ const TABLE_TAG_FLAGS: &[(u32, GlyphTableFlags)] = &[ (tag::EBDT, GlyphTableFlags::EBDT), ]; -impl Font { +impl<'a> Font<'a> { /// Construct a new instance from a type that can supply font tables. /// /// Returns `None` if the font was able to be read but no supported `cmap` sub-table was /// able to be found. The lack of such a table prevents glyph mapping. - pub fn new(provider: T) -> Result>, ParseError> { - let cmap_table = read_and_box_table(&provider, tag::CMAP)?; + pub fn new( + provider: impl Into>, + ) -> Result>, ParseError> { + let provider = provider.into(); + + let cmap_table = read_and_box_table(&*provider, tag::CMAP)?; match charmap_info(&cmap_table)? { Some((cmap_subtable_encoding, cmap_subtable_offset)) => { let maxp_table = ReadScope::new(&provider.read_table_data(tag::MAXP)?).read::()?; - let hmtx_table = read_and_box_table(&provider, tag::HMTX)?; + let hmtx_table = read_and_box_table(&*provider, tag::HMTX)?; let hhea_table = ReadScope::new(&provider.read_table_data(tag::HHEA)?).read::()?; @@ -472,7 +476,7 @@ impl Font { } else { ch as u32 - 0xF000 }; - let provider = &self.font_table_provider; + let provider = &*self.font_table_provider; let first_char = if let Ok(Some(us_first_char_index)) = self.os2_us_first_char_index.get_or_load(|| { load_os2_table(provider)? @@ -526,8 +530,8 @@ impl Font { }) } - pub fn glyph_names<'a>(&self, ids: &[u16]) -> Vec> { - let post = read_and_box_optional_table(&self.font_table_provider, tag::POST) + pub fn glyph_names(&self, ids: &[u16]) -> Vec> { + let post = read_and_box_optional_table(&*self.font_table_provider, tag::POST) .ok() .and_then(convert::identity); let cmap = ReadScope::new(self.cmap_subtable_data()) @@ -641,7 +645,7 @@ impl Font { } fn embedded_images(&mut self) -> Result>, ParseError> { - let provider = &self.font_table_provider; + 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(|| { @@ -690,7 +694,7 @@ impl Font { } pub fn vertical_advance(&mut self, glyph: u16) -> Option { - let provider = &self.font_table_provider; + let provider = &*self.font_table_provider; let vmtx = self .vmtx_table .get_or_load(|| { @@ -714,7 +718,7 @@ impl Font { } pub fn os2_table(&self) -> Result, ParseError> { - load_os2_table(&self.font_table_provider) + load_os2_table(&*self.font_table_provider) } pub fn gdef_table(&mut self) -> Result>, ParseError> { @@ -819,17 +823,14 @@ impl GlyphCache { } } -fn read_and_box_table( - provider: &impl FontTableProvider, - tag: u32, -) -> Result, ParseError> { +fn read_and_box_table(provider: &dyn FontTableProvider, tag: u32) -> Result, ParseError> { provider .read_table_data(tag) .map(|table| Box::from(table.into_owned())) } fn read_and_box_optional_table( - provider: &impl FontTableProvider, + provider: &dyn FontTableProvider, tag: u32, ) -> Result>, ParseError> { Ok(provider @@ -837,7 +838,7 @@ fn read_and_box_optional_table( .map(|table| Box::from(table.into_owned()))) } -fn load_os2_table(provider: &impl FontTableProvider) -> Result, ParseError> { +fn load_os2_table(provider: &dyn FontTableProvider) -> Result, ParseError> { provider .table_data(tag::OS_2)? .map(|data| ReadScope::new(&data).read_dep::(data.len())) @@ -845,7 +846,7 @@ fn load_os2_table(provider: &impl FontTableProvider) -> Result, Pars } fn load_cblc_cbdt( - provider: &impl FontTableProvider, + provider: &dyn FontTableProvider, bitmap_location_table_tag: u32, bitmap_data_table_tag: u32, ) -> Result<(tables::CBLC, tables::CBDT), ParseError> { @@ -863,7 +864,7 @@ fn load_cblc_cbdt( } fn load_sbix( - provider: &impl FontTableProvider, + provider: &dyn FontTableProvider, num_glyphs: usize, ) -> Result { let sbix_data = read_and_box_table(provider, tag::SBIX)?; @@ -872,7 +873,7 @@ fn load_sbix( }) } -fn load_svg(provider: &impl FontTableProvider) -> Result { +fn load_svg(provider: &dyn FontTableProvider) -> Result { let svg_data = read_and_box_table(provider, tag::SVG)?; tables::Svg::try_new(svg_data, |data| ReadScope::new(data).read::>()) } @@ -1012,7 +1013,7 @@ mod tests { let font_table_provider = opentype_file .table_provider(0) .expect("error reading font file"); - let font = Font::new(Box::new(font_table_provider)) + let font = Font::new(font_table_provider) .expect("error reading font data") .expect("missing required font tables"); diff --git a/src/glyph_position.rs b/src/glyph_position.rs index 2ad2a46..d61bab0 100644 --- a/src/glyph_position.rs +++ b/src/glyph_position.rs @@ -14,16 +14,12 @@ use std::convert::TryFrom; use crate::context::Glyph; use crate::error::ParseError; use crate::gpos::{Info, Placement}; -use crate::tables::FontTableProvider; use crate::unicode::codepoint::is_upright_char; use crate::Font; /// Used to calculate the position of shaped glyphs. -pub struct GlyphLayout<'f, 'i, T> -where - T: FontTableProvider, -{ - font: &'f mut Font, +pub struct GlyphLayout<'f, 'i, 's> { + font: &'f mut Font<'s>, infos: &'i [Info], direction: TextDirection, vertical: bool, @@ -50,7 +46,7 @@ pub enum TextDirection { RightToLeft, } -impl<'f, 'i, T: FontTableProvider> GlyphLayout<'f, 'i, T> { +impl<'f, 'i, 's> GlyphLayout<'f, 'i, 's> { /// Construct a new `GlyphLayout` instance. /// /// **Arguments** @@ -60,7 +56,7 @@ impl<'f, 'i, T: FontTableProvider> GlyphLayout<'f, 'i, T> { /// * `direction` — the horizontal text layout direction. /// * `vertical` — `true` if the text is being laid out top to bottom. pub fn new( - font: &'f mut Font, + font: &'f mut Font<'s>, infos: &'i [Info], direction: TextDirection, vertical: bool, @@ -325,8 +321,8 @@ fn sum_advance(positions: Option<&[GlyphPosition]>) -> (i32, i32) { }) } -fn glyph_advance( - font: &mut Font, +fn glyph_advance<'f>( + font: &mut Font<'f>, info: &Info, vertical: bool, ) -> Result<(i32, i32), ParseError> { diff --git a/src/tables.rs b/src/tables.rs index 73cf63d..2db348c 100644 --- a/src/tables.rs +++ b/src/tables.rs @@ -38,7 +38,11 @@ pub struct Fixed(i32); /// The value is represented as a signed 64-bit integer. type LongDateTime = i64; -pub trait FontTableProvider { +pub trait SfntVersion { + fn sfnt_version(&self) -> u32; +} + +pub trait FontTableProvider: SfntVersion { /// Return data for the specified table if present fn table_data<'a>(&'a self, tag: u32) -> Result>, ParseError>; @@ -49,8 +53,13 @@ pub trait FontTableProvider { } } -pub trait SfntVersion { - fn sfnt_version(&self) -> u32; +impl<'a, T> From for Box +where + T: FontTableProvider + 'a, +{ + fn from(provider: T) -> Self { + Box::new(provider) + } } /// The F2DOT14 format consists of a signed, 2’s complement integer and an unsigned fraction. diff --git a/tests/indic.rs b/tests/indic.rs index ce213ae..b9b501f 100644 --- a/tests/indic.rs +++ b/tests/indic.rs @@ -17,12 +17,12 @@ use allsorts::error::ShapingError; use allsorts::gsub::{self, FeatureMask, Features, RawGlyph}; use allsorts::scripts::preprocess_text; use allsorts::tables::cmap::CmapSubtable; -use allsorts::tables::{FontTableProvider, OpenTypeFont}; +use allsorts::tables::OpenTypeFont; use allsorts::{tag, Font, DOTTED_CIRCLE}; // Variant of `bin/shape::shape_ttf` -fn shape_ttf_indic<'a, T: FontTableProvider>( - font: &mut Font, +fn shape_ttf_indic( + font: &mut Font<'_>, script_tag: u32, opt_lang_tag: Option, text: &str, diff --git a/tests/khmer.rs b/tests/khmer.rs index 4a835f2..48a160c 100644 --- a/tests/khmer.rs +++ b/tests/khmer.rs @@ -17,12 +17,12 @@ use allsorts::error::ShapingError; use allsorts::gsub::{self, FeatureMask, Features}; use allsorts::scripts::preprocess_text; use allsorts::tables::cmap::CmapSubtable; -use allsorts::tables::{FontTableProvider, OpenTypeFont}; +use allsorts::tables::OpenTypeFont; use allsorts::{tag, Font, DOTTED_CIRCLE}; // Variant of `bin/shape::shape_ttf` -fn shape_ttf_khmer<'a, T: FontTableProvider>( - font: &mut Font, +fn shape_ttf_khmer( + font: &mut Font<'_>, script_tag: u32, lang_tag: Option, text: &str, diff --git a/tests/opentype.rs b/tests/opentype.rs index 1c18bdb..ae88a77 100644 --- a/tests/opentype.rs +++ b/tests/opentype.rs @@ -17,9 +17,7 @@ use allsorts::tables::glyf::{ BoundingBox, GlyfRecord, GlyfTable, Glyph, GlyphData, Point, SimpleGlyph, SimpleGlyphFlag, }; use allsorts::tables::loca::LocaTable; -use allsorts::tables::{ - Fixed, FontTableProvider, HeadTable, IndexToLocFormat, MaxpTable, OpenTypeData, OpenTypeFont, -}; +use allsorts::tables::{Fixed, HeadTable, IndexToLocFormat, MaxpTable, OpenTypeData, OpenTypeFont}; use allsorts::{tag, Font, DOTTED_CIRCLE}; use crate::common::read_fixture; @@ -207,8 +205,8 @@ fn test_decode_cmap_format_2() { // aots::cmap2_test1 } -fn shape<'a, T: FontTableProvider>( - font: &mut Font, +fn shape( + font: &mut Font, script_tag: u32, opt_lang_tag: Option, text: &str,