use std::io::Result;
use crate::metrics::Metrics;
use crate::{Axes, Characters, Features, Glyph, Names, Palettes, Tables};
pub struct Font {
case: Box<dyn Case>,
}
macro_rules! implement {
(
$(
$(#[$attribute:meta])*
fn $function:ident($($argument_name:ident: $argument_type:ty),*) -> $type:ty;
)+
) => (
pub trait Case {
$(
$(#[$attribute])*
fn $function(&mut self $(, $argument_name: $argument_type)*) -> Result<$type>;
)+
}
impl Font {
$(
$(#[$attribute])*
#[inline]
pub fn $function(&mut self $(, $argument_name: $argument_type)*) -> Result<$type> {
self.case.$function($($argument_name),*)
}
)+
}
);
}
implement! {
fn axes() -> Axes;
fn characters() -> Characters;
fn features() -> Features;
fn metrics() -> Metrics;
fn names() -> Names;
fn palettes() -> Palettes;
fn tables() -> Tables;
fn glyph(character: char) -> Option<Glyph>;
}
pub fn read<T: typeface::tape::Read + 'static>(mut tape: T) -> Result<Vec<Font>> {
use opentype::truetype::Tag;
let tag = tape.peek::<Tag>()?;
if opentype::accept(&tag) {
Ok(crate::formats::opentype::read(tape)?
.into_iter()
.map(|font| Font {
case: Box::new(font),
})
.collect())
} else if webtype::accept(&tag) {
Ok(crate::formats::webtype::read(tape)?
.into_iter()
.map(|font| Font {
case: Box::new(font),
})
.collect())
} else {
error!("found an unknown file format")
}
}