font/
font.rs

1use std::io::Result;
2
3use crate::{Axes, Characters, Features, Glyph, Metrics, Names, Palettes, Tables, Timestamps};
4
5/// A font.
6pub 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        /// A type that represents a font in a specific format.
24        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    /// Return the axes.
52    fn axes() -> Axes;
53    /// Return the characters.
54    fn characters() -> Characters;
55    /// Return the features.
56    fn features() -> Features;
57    /// Return the metrics.
58    fn metrics() -> Metrics;
59    /// Return the names.
60    fn names() -> Names;
61    /// Return the palettes.
62    fn palettes() -> Palettes;
63    /// Return the tables.
64    fn tables() -> Tables;
65    /// Return the timestamps.
66    fn timestamps() -> Timestamps;
67    /// Return the glyph of a character.
68    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}