1extern crate nalgebra as na;
10
11use ttf_parser::{Face, GlyphId, OutlineBuilder};
12
13use fdsm::{
14 bezier::{Point, Segment},
15 shape::{Contour, Shape},
16};
17
18#[cfg(test)]
19mod tests;
20
21pub fn load_shape_from_face(face: &Face, glyph_id: GlyphId) -> Shape<Contour> {
23 let mut builder = ShapeBuilder {
24 shape: Shape::default(),
25 start_point: None,
26 last_point: None,
27 };
28 face.outline_glyph(glyph_id, &mut builder);
29 builder.shape
30}
31
32#[derive(Debug)]
33struct ShapeBuilder {
34 shape: Shape<Contour>,
35 start_point: Option<Point>,
36 last_point: Option<Point>,
37}
38
39impl OutlineBuilder for ShapeBuilder {
40 fn move_to(&mut self, x: f32, y: f32) {
41 if let Some(contour) = self.shape.contours.last_mut() {
43 if self.start_point != self.last_point {
44 contour.segments.push(Segment::line(
45 self.last_point.unwrap(),
46 self.start_point.unwrap(),
47 ));
48 }
49 }
50 self.start_point = Some(Point::new(x.into(), y.into()));
51 self.last_point = self.start_point;
52 self.shape.contours.push(Contour::default());
53 }
54
55 fn line_to(&mut self, x: f32, y: f32) {
56 let next_point = Point::new(x.into(), y.into());
58 self.shape
59 .contours
60 .last_mut()
61 .unwrap()
62 .segments
63 .push(Segment::line(self.last_point.unwrap(), next_point));
64 self.last_point = Some(next_point);
65 }
66
67 fn quad_to(&mut self, x1: f32, y1: f32, x: f32, y: f32) {
68 let next_point = Point::new(x.into(), y.into());
70 self.shape
71 .contours
72 .last_mut()
73 .unwrap()
74 .segments
75 .push(Segment::quad(
76 self.last_point.unwrap(),
77 Point::new(x1.into(), y1.into()),
78 next_point,
79 ));
80 self.last_point = Some(next_point);
81 }
82
83 fn curve_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32) {
84 let next_point = Point::new(x.into(), y.into());
86 self.shape
87 .contours
88 .last_mut()
89 .unwrap()
90 .segments
91 .push(Segment::cubic(
92 self.last_point.unwrap(),
93 Point::new(x1.into(), y1.into()),
94 Point::new(x2.into(), y2.into()),
95 next_point,
96 ));
97 self.last_point = Some(next_point);
98 }
99
100 fn close(&mut self) {
101 if let Some(contour) = self.shape.contours.last_mut() {
103 if self.start_point != self.last_point {
104 contour.segments.push(Segment::line(
105 self.last_point.take().unwrap(),
106 self.start_point.take().unwrap(),
107 ));
108 }
109 }
110 }
111}