Skip to content

Commit

Permalink
Font made indepedent on provider, generic replaced with dyn
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-kolarik committed Aug 5, 2022
1 parent 4fdb3cd commit d77f5fe
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 46 deletions.
45 changes: 23 additions & 22 deletions src/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: FontTableProvider> {
pub font_table_provider: T,
pub struct Font<'a> {
pub font_table_provider: Box<dyn FontTableProvider + 'a>,
cmap_table: Box<[u8]>,
pub maxp_table: MaxpTable,
hmtx_table: Box<[u8]>,
Expand Down Expand Up @@ -149,19 +149,23 @@ const TABLE_TAG_FLAGS: &[(u32, GlyphTableFlags)] = &[
(tag::EBDT, GlyphTableFlags::EBDT),
];

impl<T: FontTableProvider> Font<T> {
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<Option<Font<T>>, ParseError> {
let cmap_table = read_and_box_table(&provider, tag::CMAP)?;
pub fn new(
provider: impl Into<Box<dyn FontTableProvider + 'a>>,
) -> Result<Option<Font<'a>>, 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::<MaxpTable>()?;
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::<HheaTable>()?;

Expand Down Expand Up @@ -472,7 +476,7 @@ impl<T: FontTableProvider> Font<T> {
} 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)?
Expand Down Expand Up @@ -526,8 +530,8 @@ impl<T: FontTableProvider> Font<T> {
})
}

pub fn glyph_names<'a>(&self, ids: &[u16]) -> Vec<Cow<'a, str>> {
let post = read_and_box_optional_table(&self.font_table_provider, tag::POST)
pub fn glyph_names(&self, ids: &[u16]) -> Vec<Cow<'a, str>> {
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())
Expand Down Expand Up @@ -641,7 +645,7 @@ impl<T: FontTableProvider> Font<T> {
}

fn embedded_images(&mut self) -> Result<Option<Rc<Images>>, 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(|| {
Expand Down Expand Up @@ -690,7 +694,7 @@ impl<T: FontTableProvider> Font<T> {
}

pub fn vertical_advance(&mut self, glyph: u16) -> Option<u16> {
let provider = &self.font_table_provider;
let provider = &*self.font_table_provider;
let vmtx = self
.vmtx_table
.get_or_load(|| {
Expand All @@ -714,7 +718,7 @@ impl<T: FontTableProvider> Font<T> {
}

pub fn os2_table(&self) -> Result<Option<Os2>, ParseError> {
load_os2_table(&self.font_table_provider)
load_os2_table(&*self.font_table_provider)
}

pub fn gdef_table(&mut self) -> Result<Option<Rc<GDEFTable>>, ParseError> {
Expand Down Expand Up @@ -819,33 +823,30 @@ impl GlyphCache {
}
}

fn read_and_box_table(
provider: &impl FontTableProvider,
tag: u32,
) -> Result<Box<[u8]>, ParseError> {
fn read_and_box_table(provider: &dyn FontTableProvider, tag: u32) -> Result<Box<[u8]>, 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<Option<Box<[u8]>>, ParseError> {
Ok(provider
.table_data(tag)?
.map(|table| Box::from(table.into_owned())))
}

fn load_os2_table(provider: &impl FontTableProvider) -> Result<Option<Os2>, ParseError> {
fn load_os2_table(provider: &dyn FontTableProvider) -> Result<Option<Os2>, ParseError> {
provider
.table_data(tag::OS_2)?
.map(|data| ReadScope::new(&data).read_dep::<Os2>(data.len()))
.transpose()
}

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> {
Expand All @@ -863,7 +864,7 @@ fn load_cblc_cbdt(
}

fn load_sbix(
provider: &impl FontTableProvider,
provider: &dyn FontTableProvider,
num_glyphs: usize,
) -> Result<tables::Sbix, ParseError> {
let sbix_data = read_and_box_table(provider, tag::SBIX)?;
Expand All @@ -872,7 +873,7 @@ fn load_sbix(
})
}

fn load_svg(provider: &impl FontTableProvider) -> Result<tables::Svg, ParseError> {
fn load_svg(provider: &dyn FontTableProvider) -> Result<tables::Svg, ParseError> {
let svg_data = read_and_box_table(provider, tag::SVG)?;
tables::Svg::try_new(svg_data, |data| ReadScope::new(data).read::<SvgTable<'_>>())
}
Expand Down Expand Up @@ -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");

Expand Down
16 changes: 6 additions & 10 deletions src/glyph_position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>,
pub struct GlyphLayout<'f, 'i, 's> {
font: &'f mut Font<'s>,
infos: &'i [Info],
direction: TextDirection,
vertical: bool,
Expand All @@ -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**
Expand All @@ -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<T>,
font: &'f mut Font<'s>,
infos: &'i [Info],
direction: TextDirection,
vertical: bool,
Expand Down Expand Up @@ -325,8 +321,8 @@ fn sum_advance(positions: Option<&[GlyphPosition]>) -> (i32, i32) {
})
}

fn glyph_advance<T: FontTableProvider>(
font: &mut Font<T>,
fn glyph_advance<'f>(
font: &mut Font<'f>,
info: &Info,
vertical: bool,
) -> Result<(i32, i32), ParseError> {
Expand Down
15 changes: 12 additions & 3 deletions src/tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Option<Cow<'a, [u8]>>, ParseError>;

Expand All @@ -49,8 +53,13 @@ pub trait FontTableProvider {
}
}

pub trait SfntVersion {
fn sfnt_version(&self) -> u32;
impl<'a, T> From<T> for Box<dyn FontTableProvider + 'a>
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.
Expand Down
6 changes: 3 additions & 3 deletions tests/indic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>,
fn shape_ttf_indic(
font: &mut Font<'_>,
script_tag: u32,
opt_lang_tag: Option<u32>,
text: &str,
Expand Down
6 changes: 3 additions & 3 deletions tests/khmer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>,
fn shape_ttf_khmer(
font: &mut Font<'_>,
script_tag: u32,
lang_tag: Option<u32>,
text: &str,
Expand Down
8 changes: 3 additions & 5 deletions tests/opentype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -207,8 +205,8 @@ fn test_decode_cmap_format_2() {
// aots::cmap2_test1
}

fn shape<'a, T: FontTableProvider>(
font: &mut Font<T>,
fn shape(
font: &mut Font,
script_tag: u32,
opt_lang_tag: Option<u32>,
text: &str,
Expand Down

0 comments on commit d77f5fe

Please sign in to comment.