Skip to main content

glyph_bbox/
lib.rs

1#[macro_use]
2extern crate serde_derive;
3
4pub mod dataset {
5    extern crate serde;
6    extern crate serde_json;
7
8    use std::collections::HashMap;
9    use std::fs::{read_to_string, File};
10    use std::io::{Error, Write};
11
12    use serde::Serialize;
13    use serde_json::Serializer as JsonSerializer;
14
15    pub type Index = i32;
16    pub type Dimension = f32;
17    pub type BoundingBox = Vec<Dimension>;
18    pub type FontFace = String;
19    pub type FontSize = String;
20    pub type FontFaces = Vec<FontFace>;
21    pub type FontSizes = Vec<FontSize>;
22    pub type Data = HashMap<FontFace, HashMap<FontSize, FontData>>;
23
24    #[derive(Debug, Serialize, Deserialize, Clone)]
25    pub struct FontData {
26        pub boxes: Vec<BoundingBox>,
27        pub signals: Signals,
28    }
29
30    #[derive(Debug, Serialize, Deserialize, Clone)]
31    pub struct Signals {
32        mean: BoundingBox,
33    }
34
35    #[derive(Debug, Serialize, Deserialize, Clone)]
36    pub struct FontConfig {
37        pub faces: FontFaces,
38        pub sizes: FontSizes,
39    }
40
41    #[derive(Debug, Serialize, Deserialize, Clone)]
42    pub struct CharConfig {
43        pub offset: Index,
44        pub range: Index,
45    }
46
47    #[derive(Debug, Serialize, Deserialize, Clone)]
48    pub struct DataSet {
49        pub error: Option<String>,
50        pub config: DataSetConfig,
51        pub data: Data,
52    }
53
54    #[derive(Debug, Serialize, Deserialize, Clone)]
55    pub struct DataSetConfig {
56        pub font: FontConfig,
57        pub char: CharConfig,
58        pub signals: CharConfig,
59    }
60
61    #[derive(Debug, Deserialize)]
62    pub struct WriteOptions {
63        pub filename: String,
64        pub format: Format,
65    }
66
67    pub type ReadOptions = WriteOptions;
68
69    #[derive(Debug, Deserialize)]
70    pub enum Format {
71        JSON,
72    }
73
74    pub struct BoundingBoxRenderOptions {
75        pub face: FontFace,
76        pub size: FontSize,
77    }
78
79    impl DataSet {
80        pub fn from_file(opts: ReadOptions) -> DataSet {
81            match opts.format {
82                Format::JSON => {
83                    let json_file_str = read_to_string(opts.filename).expect("file not found");
84
85                    DataSet::from_json_string(&json_file_str)
86                }
87            }
88        }
89
90        pub fn from_json_string(s: &String) -> DataSet {
91            serde_json::from_str(&s).expect("error while reading json")
92        }
93
94        pub fn write(&self, opts: WriteOptions) -> Result<(), Error> {
95            let mut buf = Vec::new();
96
97            match opts.format {
98                Format::JSON => self.serialize(&mut JsonSerializer::new(&mut buf)).unwrap(),
99            }
100
101            let mut file = File::create(opts.filename).unwrap();
102
103            file.write_all(buf.as_ref())
104        }
105
106        pub fn bounding_box(&self, s: &str, opts: BoundingBoxRenderOptions) -> Option<BoundingBox> {
107            if !&self.data.contains_key(opts.face.as_str())
108                || !&self.data[opts.face.as_str()].contains_key(opts.size.as_str())
109            {
110                ()
111            }
112
113            let mut width: Dimension = 0.0;
114            let mut height: Dimension = 0.0;
115
116            let mut buf = [0; 2];
117
118            for c in s.chars() {
119                let char_box = match &self.data[opts.face.as_str()][opts.size.as_str()]
120                    .boxes
121                    .get(c.encode_utf16(&mut buf)[0] as usize)
122                {
123                    Some(val) => val.to_vec(),
124                    None => self.data[opts.face.as_str()][opts.size.as_str()]
125                        .signals
126                        .mean
127                        .to_vec(),
128                };
129
130                width += char_box[0];
131
132                if char_box[1] > height {
133                    height = char_box[1];
134                }
135            }
136
137            Some(vec![width, height])
138        }
139    }
140}