1use std::io::Result;
2
3use crate::{Axes, Characters, Features, Glyph, Metrics, Names, Palettes, Tables, Timestamps};
4
5pub struct Font<T> {
7 format: Format<T>,
8}
9
10enum Format<T> {
11 OpenType(crate::formats::opentype::Font<T>),
12 #[cfg(feature = "webtype")]
13 WebType(crate::formats::webtype::Font<T>),
14}
15
16macro_rules! implement {
17 (
18 $(
19 $(#[$attribute:meta])*
20 fn $function:ident($($argument_name:ident: $argument_type:ty),*) -> $type:ty;
21 )+
22 ) => (
23 pub trait Case {
25 $(
26 $(#[$attribute])*
27 fn $function(&mut self $(, $argument_name: $argument_type)*) -> Result<$type>;
28 )+
29 }
30
31 impl<T> Font<T>
32 where
33 T: crate::Read,
34 {
35 $(
36 $(#[$attribute])*
37 #[inline]
38 pub fn $function(&mut self $(, $argument_name: $argument_type)*) -> Result<$type> {
39 match self.format {
40 Format::OpenType(ref mut font) => font.$function($($argument_name),*),
41 #[cfg(feature = "webtype")]
42 Format::WebType(ref mut font) => font.$function($($argument_name),*),
43 }
44 }
45 )+
46 }
47 );
48}
49
50implement! {
51 fn axes() -> Axes;
53 fn characters() -> Characters;
55 fn features() -> Features;
57 fn metrics() -> Metrics;
59 fn names() -> Names;
61 fn palettes() -> Palettes;
63 fn tables() -> Tables;
65 fn timestamps() -> Timestamps;
67 fn glyph(character: char) -> Option<Glyph>;
69}
70
71pub fn read<T: crate::Read>(mut tape: T) -> Result<Vec<Font<T>>> {
72 use opentype::truetype::Tag;
73
74 let tag = tape.peek::<Tag>()?;
75 if opentype::accept(&tag) {
76 return Ok(crate::formats::opentype::read(tape)?
77 .into_iter()
78 .map(|font| Font {
79 format: Format::OpenType(font),
80 })
81 .collect());
82 }
83 #[cfg(feature = "webtype")]
84 if webtype::accept(&tag) {
85 return Ok(crate::formats::webtype::read(tape)?
86 .into_iter()
87 .map(|font| Font {
88 format: Format::WebType(font),
89 })
90 .collect());
91 }
92 error!("found an unknown file format")
93}