digital_ink_library/
lib.rs

1pub mod stroke;
2pub mod sketch;
3pub mod boundingbox;
4pub mod serialization;
5
6#[cfg(test)]
7mod tests {
8    use serde_json::json;
9    use tempfile::tempdir;
10
11    use crate::boundingbox::BoundingBox;
12    use crate::serialization::json_serializer;
13    use crate::sketch::Sketch;
14    use crate::stroke::Stroke;
15    use crate::stroke::StrokeBuilder;
16
17    extern crate serde_json;
18
19    #[test]
20    fn stroke() {
21        let x = vec![10., 20., 30., 40., 50.];
22        let y = vec![1., 2., 3., 4., 5.];
23        let timestamp = vec![1, 2, 3, 4, 5];
24        let pressure = vec![1., 2., 3., 4., 5.];
25
26        let stroke = Stroke::new(x, y, timestamp, pressure);
27
28        assert_eq!(stroke.x_min(), 10.);
29        assert_eq!(stroke.x_max(), 50.);
30        assert_eq!(stroke.y_min(), 1.);
31        assert_eq!(stroke.y_max(), 5.);
32        assert_eq!(stroke.timestamp_min(), 1);
33        assert_eq!(stroke.timestamp_max(), 5);
34        assert_eq!(stroke.pressure_min(), 1.);
35        assert_eq!(stroke.pressure_max(), 5.);
36        assert_eq!(stroke.len(), 5);
37    }
38
39    #[test]
40    fn bounding_box_constructor() {
41        BoundingBox::new(0., 0., 1., 1.);
42    }
43
44    #[test]
45    #[should_panic]
46    fn bounding_box_constructor_switched_bounds() {
47        BoundingBox::new(2., 1., 1., 0.);
48    }
49
50    #[test]
51    #[should_panic]
52    fn bounding_box_constructor_switched_bounds_2() {
53        BoundingBox::new(0., 1., 0., -1.);
54    }
55
56    #[test]
57    #[should_panic]
58    fn bounding_box_constructor_switched_bounds_3() {
59        BoundingBox::new(0., 2., 1., 1.);
60    }
61
62    #[test]
63    #[should_panic]
64    fn bounding_box_constructor_switched_bounds_4() {
65        BoundingBox::new(-1., 1., 0., 0.);
66    }
67
68    #[test]
69    #[should_panic]
70    fn bounding_box_constructor_switched_bounds_5() {
71        BoundingBox::new(1., 0., 0., 1.);
72    }
73
74    #[test]
75    fn bounding_box_merge() {
76        let bb1 = BoundingBox::new(0., 0., 1., 1.);
77        let bb1a = BoundingBox::new(0.5, 0.5, 1.5, 1.5);
78        let bb2 = BoundingBox::new(-2., -2., -1., -1.);
79
80        let bb1_bb1a = bb1.merge(&bb1a);
81
82        assert_eq!(bb1_bb1a, bb1a.merge(&bb1));
83        assert_eq!(bb1_bb1a.x_min, 0.);
84        assert_eq!(bb1_bb1a.x_max, 1.5);
85        assert_eq!(bb1_bb1a.y_min, 0.);
86        assert_eq!(bb1_bb1a.y_max, 1.5);
87        assert_eq!(bb1_bb1a.width, 1.5);
88        assert_eq!(bb1_bb1a.height, 1.5);
89
90        let bb2_bb1 = bb1.merge(&bb2);
91
92        assert_eq!(bb2_bb1, bb2.merge(&bb1));
93        assert_eq!(bb2_bb1.x_min, -2.);
94        assert_eq!(bb2_bb1.x_max, 1.);
95        assert_eq!(bb2_bb1.y_min, -2.);
96        assert_eq!(bb2_bb1.y_max, 1.);
97        assert_eq!(bb2_bb1.width, 3.);
98        assert_eq!(bb2_bb1.height, 3.);
99    }
100
101    #[test]
102    fn bounding_box_intersects() {
103        let bb1 = BoundingBox::new(0., 0., 1., 1.);
104        let bb1a = BoundingBox::new(0.5, 0.5, 1.5, 1.5);
105        let bb2 = BoundingBox::new(-2., -2., -1., -1.);
106
107        let bb1_intersects_bb2 = bb1.intersects(&bb2);
108        let bb2_intersects_bb1 = bb2.intersects(&bb1);
109
110        assert_eq!(bb2_intersects_bb1, bb1_intersects_bb2);
111        assert!(!bb2_intersects_bb1);
112
113        let bb3 = BoundingBox::new(0.25, 0.25, 0.75, 0.75);
114        let bb1_intersects_bb3 = bb1.intersects(&bb3);
115        let bb3_intersects_bb1 = bb3.intersects(&bb1);
116
117        assert_eq!(bb1_intersects_bb3, bb3_intersects_bb1);
118        assert!(bb1_intersects_bb3);
119        assert!(!bb2.intersects(&bb3));
120        assert!(bb1.intersects(&bb1a));
121        assert!(bb1a.intersects(&bb1));
122    }
123
124    #[test]
125    fn bounding_box_get_intersection() {
126        let a = BoundingBox::new(0., 0., 2., 2.);
127        let b = BoundingBox::new(1., 1., 3., 3.);
128
129        let a_b = a.get_intersection(&b).unwrap();
130        assert_eq!(a_b, b.get_intersection(&a).unwrap());
131        assert_eq!(a_b.x_min, 1.);
132        assert_eq!(a_b.x_max, 2.);
133        assert_eq!(a_b.y_min, 1.);
134        assert_eq!(a_b.y_max, 2.);
135        assert_eq!(a_b.width, 1.);
136        assert_eq!(a_b.height, 1.);
137
138        let c = BoundingBox::new(0., 0., 2., 1.);
139        let d = BoundingBox::new(1., -1., 3., 2.);
140
141        let c_d = c.get_intersection(&d).unwrap();
142        assert_eq!(c_d, d.get_intersection(&c).unwrap());
143        assert_eq!(c_d.x_min, 1.);
144        assert_eq!(c_d.y_min, 0.);
145        assert_eq!(c_d.x_max, 2.);
146        assert_eq!(c_d.y_max, 1.);
147        assert_eq!(c_d.width, 1.);
148        assert_eq!(c_d.height, 1.);
149
150        let e = BoundingBox::new(0., 0., 1., 1.);
151        let f = BoundingBox::new(2., 2., 3., 3.);
152
153        let e_f = e.get_intersection(&f);
154        assert_eq!(e_f, f.get_intersection(&e));
155        assert_eq!(e_f, None);
156
157        let g = BoundingBox::new(0., 0., 3., 3.);
158        let h = BoundingBox::new(1., 1., 2., 2.);
159
160        let g_h = g.get_intersection(&h).unwrap();
161        assert_eq!(g_h, h.get_intersection(&g).unwrap());
162        assert_eq!(g_h.x_min, 1.);
163        assert_eq!(g_h.y_min, 1.);
164        assert_eq!(g_h.x_max, 2.);
165        assert_eq!(g_h.y_max, 2.);
166        assert_eq!(g_h.width, 1.);
167        assert_eq!(g_h.height, 1.);
168
169        let i = BoundingBox::new(0., 0., 2., 1.);
170        let j = BoundingBox::new(1., 0., 3., 1.);
171
172        let i_j = i.get_intersection(&j).unwrap();
173        assert_eq!(i_j, j.get_intersection(&i).unwrap());
174        assert_eq!(i_j.x_min, 1.);
175        assert_eq!(i_j.y_min, 0.);
176        assert_eq!(i_j.x_max, 2.);
177        assert_eq!(i_j.y_max, 1.);
178        assert_eq!(i_j.width, 1.);
179        assert_eq!(i_j.height, 1.);
180    }
181
182    #[test]
183    fn sketch() {
184        let x = vec![1., 2., 3., 4., 5., 32.];
185        let y = vec![1., 2., 3., 4., 5.];
186        let timestamp = vec![1, 2, 3, 4];
187        let pressure = vec![1., 2., 3., 4.];
188
189        let stroke = Stroke::new(x, y, timestamp, pressure);
190
191        let strokes = vec![stroke.clone()];
192        let mut sketch = Sketch::new(strokes);
193        assert_eq!(sketch.len(), 1);
194
195        sketch.add_stroke(stroke);
196        assert_eq!(sketch.len(), 2);
197    }
198
199    #[test]
200    fn stroke_builder() {
201        let mut stroke_builder = StrokeBuilder::new();
202        stroke_builder.add_point(1., 2., 3, 4.);
203        stroke_builder.add_point(2., 3., 4, 5.);
204        let stroke = stroke_builder.build();
205
206        assert_eq!(stroke.len(), 2);
207    }
208
209    #[test]
210    fn meta() {
211        let x = vec![1., 2., 3., 4., 5., 32.];
212        let y = vec![1., 2., 3., 4., 5.];
213        let timestamp = vec![1, 2, 3, 4];
214        let pressure = vec![1., 2., 3., 4.];
215
216        let mut stroke = Stroke::new(x, y, timestamp, pressure);
217        let meta_stroke = stroke.clone();
218        stroke.meta.insert(String::from("someVal"), json!(7.1));
219        stroke.meta.insert(String::from("someArr"), json!([1, 2, 3, 4]));
220        stroke.meta.insert(String::from("someVec"), json!(vec![1., 2., 3., 4., 5., 32.]));
221        stroke.meta.insert(String::from("someObj"), json!(meta_stroke));
222
223
224        let strokes = vec![stroke.clone(), stroke.clone()];
225        let sketch = Sketch::new(strokes);
226
227        json_serializer::dumps_stroke(&stroke);
228        json_serializer::dumps_sketch(&sketch);
229
230        let val_some_val = stroke.meta.get("someVal").unwrap().clone();
231        let val_some_arr = stroke.meta.get("someArr").unwrap().clone();
232        let val_some_vec = stroke.meta.get("someVec").unwrap().clone();
233        let val_some_obj = stroke.meta.get("someObj").unwrap().clone();
234
235        let some_val: f64 = serde_json::from_value(val_some_val).unwrap();
236        let some_arr: Vec<i32> = serde_json::from_value(val_some_arr).unwrap();
237        let some_vec: Vec<f64> = serde_json::from_value(val_some_vec).unwrap();
238        let some_obj: Stroke = serde_json::from_value(val_some_obj).unwrap();
239
240        assert_eq!(some_val, 7.1);
241        assert_eq!(some_arr, [1, 2, 3, 4]);
242        assert_eq!(some_vec, vec![1., 2., 3., 4., 5., 32.]);
243        assert_eq!(some_obj, meta_stroke);
244    }
245
246    #[test]
247    fn equals() {
248        let x0 = vec![1., 2., 3., 4., 5., 32.];
249        let y0 = vec![1., 2., 3., 4., 5.];
250        let timestamp0 = vec![1, 2, 3, 4];
251        let pressure0 = vec![1., 2., 3., 4.];
252
253        let x1 = vec![1., 2., 3., 4., 5., 32.];
254        let y1 = vec![1., 2., 3., 4., 5.];
255        let timestamp1 = vec![1, 2, 3, 4];
256        let pressure1 = vec![1., 2., 3., 4.];
257
258        let x2 = vec![2.];
259        let y2 = vec![2.];
260        let timestamp2 = vec![2];
261        let pressure2 = vec![2.];
262
263        let stroke0 = Stroke::new(x0, y0, timestamp0, pressure0);
264        let stroke1 = Stroke::new(x1, y1, timestamp1, pressure1);
265        let stroke2 = Stroke::new(x2, y2, timestamp2, pressure2);
266
267        assert_eq!(stroke0, stroke1);
268        assert_eq!(stroke1, stroke0);
269        assert_ne!(stroke0, stroke2);
270        assert_ne!(stroke2, stroke0);
271        assert_ne!(stroke1, stroke2);
272        assert_ne!(stroke2, stroke1);
273    }
274
275    #[test]
276    fn serialization() {
277        let x = vec![1., 2., 3., 4., 5., 32.];
278        let y = vec![1., 2., 3., 4., 5.];
279        let timestamp = vec![1, 2, 3, 4];
280        let pressure = vec![1., 2., 3., 4.];
281
282        let stroke = Stroke::new(x.clone(), y.clone(), timestamp.clone(), pressure.clone());
283
284        let strokes = vec![stroke.clone(), stroke.clone()];
285        let sketch = Sketch::new(strokes);
286
287        let json_stroke = json_serializer::dumps_stroke(&stroke);
288        let json_sketch = json_serializer::dumps_sketch(&sketch);
289
290        let deserialized_stroke = json_serializer::loads_stroke(json_stroke).unwrap();
291        let deserialized_sketch = json_serializer::loads_sketch(json_sketch).unwrap();
292
293        assert_eq!(deserialized_stroke.x, x);
294        assert_eq!(deserialized_stroke.y, y);
295        assert_eq!(deserialized_stroke.timestamp, timestamp);
296        assert_eq!(deserialized_stroke.pressure, pressure);
297
298        assert_eq!(stroke, deserialized_stroke);
299        assert_eq!(sketch, deserialized_sketch);
300    }
301
302    #[test]
303    fn file_writing() {
304        let x = vec![1., 2., 3., 4., 5., 32.];
305        let y = vec![1., 2., 3., 4., 5.];
306        let timestamp = vec![1, 2, 3, 4];
307        let pressure = vec![1., 2., 3., 4.];
308
309        let stroke = Stroke::new(x.clone(), y.clone(), timestamp.clone(), pressure.clone());
310        let strokes = vec![stroke.clone(), stroke.clone()];
311        let sketch = Sketch::new(strokes);
312
313        let dir = tempdir().unwrap();
314        let file_path_stroke = String::from(dir.path().join("temp_stroke.json").to_str().unwrap());
315        let file_path_sketch = String::from(dir.path().join("temp_sketch.json").to_str().unwrap());
316
317        json_serializer::dump_stroke(&stroke, &file_path_stroke);
318        json_serializer::dump_sketch(&sketch, &file_path_sketch);
319
320        let loaded_stroke = json_serializer::load_stroke(&file_path_stroke).unwrap();
321        let loaded_sketch = json_serializer::load_sketch(&file_path_sketch).unwrap();
322
323        assert_eq!(stroke, loaded_stroke);
324        assert_eq!(sketch, loaded_sketch);
325
326        let result = dir.close();
327        match result {
328            Ok(_) => assert!(true),
329            Err(_) => assert!(false),
330        }
331    }
332
333    #[test]
334    fn stroke_offset() {
335        let x = vec![0., 0., 1., 1.];
336        let y = vec![0., 1., 1., 0.];
337
338        let mut stroke = Stroke::new(x, y, vec![], vec![]);
339        stroke.offset(Some(4.2), Some(-1.));
340
341        assert_eq!(stroke.x, [4.2, 4.2, 5.2, 5.2]);
342        assert_eq!(stroke.y, [-1., 0., 0., -1.]);
343
344        assert_eq!(stroke.x_min(), 4.2);
345        assert_eq!(stroke.x_max(), 5.2);
346        assert_eq!(stroke.y_min(), -1.);
347        assert_eq!(stroke.y_max(), 0.);
348    }
349
350    #[test]
351    fn sketch_offset() {
352        let x = vec![0., 0., 1., 1.];
353        let y = vec![0., 1., 1., 0.];
354
355        let stroke_one = Stroke::new(x.to_vec(), y.to_vec(), vec![], vec![]);
356        let stroke_two = Stroke::new(x, y, vec![], vec![]);
357        let strokes = vec![stroke_one, stroke_two];
358
359        let mut sketch = Sketch::new(strokes);
360        sketch.offset(Some(4.2), Some(-1.));
361
362        assert_eq!(sketch.strokes[0].x, [4.2, 4.2, 5.2, 5.2]);
363        assert_eq!(sketch.strokes[0].y, [-1., 0., 0., -1.]);
364        assert_eq!(sketch.strokes[1].x, [4.2, 4.2, 5.2, 5.2]);
365        assert_eq!(sketch.strokes[1].y, [-1., 0., 0., -1.]);
366    }
367
368    #[test]
369    fn stroke_scale() {
370        let x = vec![0., 0., 1., 1.];
371        let y = vec![0., 1., 1., 0.];
372        let x_scaled = vec![0., 0., 4.2, 4.2];
373        let y_scaled = vec![0., -1., -1., 0.];
374
375        let mut stroke = Stroke::new(x, y, vec![], vec![]);
376        stroke.scale(Some(4.2), Some(-1.));
377
378        assert_eq!(stroke.x, x_scaled);
379        assert_eq!(stroke.y, y_scaled);
380
381        assert_eq!(stroke.x_min(), 0.);
382        assert_eq!(stroke.x_max(), 4.2);
383        assert_eq!(stroke.y_min(), -1.);
384        assert_eq!(stroke.y_max(), 0.);
385    }
386
387    #[test]
388    fn sketch_scale() {
389        let x = vec![0., 0., 1., 1.];
390        let y = vec![0., 1., 1., 0.];
391        let x_scaled = vec![0., 0., 4.2, 4.2];
392        let y_scaled = vec![0., -1., -1., 0.];
393
394        let stroke_one = Stroke::new(x.to_vec(), y.to_vec(), vec![], vec![]);
395        let stroke_two = Stroke::new(x, y, vec![], vec![]);
396        let strokes = vec![stroke_one, stroke_two];
397
398        let mut sketch = Sketch::new(strokes);
399        sketch.scale(Some(4.2), Some(-1.));
400
401        assert_eq!(sketch.strokes[0].x, x_scaled);
402        assert_eq!(sketch.strokes[0].y, y_scaled);
403        assert_eq!(sketch.strokes[1].x, x_scaled);
404        assert_eq!(sketch.strokes[1].y, y_scaled);
405    }
406
407    fn generate_sketch() -> Sketch {
408        let x1 = vec![1., 2.];
409        let y1 = vec![0.9, 0.3];
410        let x2 = vec![1.2, 1.5];
411        let y2 = vec![0.6, 0.7];
412
413        let s1 = Stroke::new(x1, y1, vec![], vec![]);
414        let s2 = Stroke::new(x2, y2, vec![], vec![]);
415        let strokes = vec![s1, s2];
416
417        return Sketch::new(strokes);
418    }
419
420    #[test]
421    fn sketch_normalize_default() {
422        let mut sketch = generate_sketch();
423        sketch.normalize(1., false);
424
425        assert_eq!(sketch.strokes[0].x[0], 0. as f64);
426        assert_eq!(sketch.strokes[0].x[1], 1. as f64);
427        assert_eq!(sketch.strokes[0].y[1], 0. as f64);
428        assert_eq!(sketch.strokes[0].y[0], 1. as f64);
429        for i in 0..sketch.strokes[1].len() {
430            let x = sketch.strokes[1].x[i];
431            let y = sketch.strokes[1].y[i];
432            assert!(x > 0.);
433            assert!(x < 1.);
434            assert!(y > 0.);
435            assert!(y < 1.);
436        }
437
438        sketch.normalize(2., false);
439        assert_eq!(sketch.strokes[0].x[1], 2. as f64);
440        assert_eq!(sketch.strokes[0].y[0], 2. as f64);
441    }
442
443    #[test]
444    fn sketch_normalize_aspect_ratio_preserving() {
445        let mut sketch = generate_sketch();
446        sketch.normalize(1., true);
447
448        assert_eq!(sketch.strokes[0].x[1], 1.);
449        assert!(sketch.strokes[0].y[0] < 1.);
450
451        sketch = generate_sketch();
452        sketch.strokes[1].y[1] = 20.;
453        sketch.normalize(1., true);
454        assert!(sketch.strokes[0].x[1] < 1.);
455        assert!(sketch.strokes[0].y[0] < 1.);
456        assert_eq!(sketch.strokes[1].y[1], 1.);
457    }
458
459    #[test]
460    fn sketch_processing() {
461        let x1 = vec![1., 2., 3., 4.];
462        let y1 = vec![1., 2., 3., 4.];
463        let t1 = vec![1, 2, 3, 4];
464        let p1 = vec![1., 1., 1., 1.];
465        let s1 = Stroke::new(x1, y1, t1, p1);
466
467        let x2 = vec![2., 3., 3., 5.];
468        let y2 = vec![5., 3., 3., 1.];
469        let t2 = vec![1, 2, 3, 4];
470        let p2 = vec![1., 1., 1., 1.];
471        let s2 = Stroke::new(x2, y2, t2, p2);
472
473        let x3 = vec![3., 3.];
474        let y3 = vec![3., 3.];
475        let t3 = vec![1, 2];
476        let p3 = vec![1., 1.];
477        let s3 = Stroke::new(x3, y3, t3, p3);
478
479        let strokes = vec![s1, s2, s3];
480        let mut sketch = Sketch::new(strokes);
481
482        sketch.remove_duplicate_dots();
483        assert_eq!(sketch.strokes[0].len(), 4);
484        assert_eq!(sketch.strokes[1].len(), 3);
485
486        sketch.remove_single_dot_strokes();
487        assert_eq!(sketch.len(), 2);
488    }
489}