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}