1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use super::super::traits::*;
use curves::*;
use curves::bezier;
use canvas::*;
use std::iter;
pub struct SimpleBrush {
}
impl SimpleBrush {
pub fn new() -> SimpleBrush {
SimpleBrush { }
}
}
impl Brush for SimpleBrush {
fn prepare_to_render<'a>(&'a self, properties: &BrushProperties) -> Box<'a+Iterator<Item=Draw>> {
Box::new(vec![
Draw::BlendMode(BlendMode::SourceOver),
Draw::StrokeColor(properties.color)
].into_iter())
}
fn to_definition(&self) -> (BrushDefinition, BrushDrawingStyle) {
(BrushDefinition::Simple, BrushDrawingStyle::Draw)
}
fn brush_points_for_raw_points(&self, points: &[RawPoint]) -> Vec<BrushPoint> {
let coords: Vec<_> = points.iter().map(|point| Coord2(point.position.0 as f64, point.position.1 as f64)).collect();
let mut distant_coords = vec![];
let mut last_point = coords[0];
distant_coords.push(last_point);
for x in 1..coords.len() {
if last_point.distance_to(&coords[x]) >= 2.0 {
last_point = coords[x];
distant_coords.push(last_point);
}
}
let curve = bezier::Curve::fit_from_points(&distant_coords, 2.0);
let mut brush_points = vec![];
if let Some(curve) = curve {
let start = curve[0].start_point();;
brush_points.push(BrushPoint {
position: (start.x() as f32, start.y() as f32),
cp1: (0.0, 0.0),
cp2: (0.0, 0.0),
width: 0.0
});
for segment in curve {
let end = segment.end_point();
let (cp1, cp2) = segment.control_points();
brush_points.push(BrushPoint {
position: (end.x() as f32, end.y() as f32),
cp1: (cp1.x() as f32, cp1.y() as f32),
cp2: (cp2.x() as f32, cp2.y() as f32),
width: 1.0
});
}
}
brush_points
}
fn render_brush<'a>(&'a self, _properties: &'a BrushProperties, points: &'a Vec<BrushPoint>) -> Box<'a+Iterator<Item=Draw>> {
if points.len() <= 1 {
return Box::new(iter::empty());
}
let preamble = vec![
Draw::NewPath,
Draw::Move(points[0].position.0, points[0].position.1)
];
let curves = points.iter()
.skip(1)
.map(|segment| Draw::BezierCurve(
(segment.position.0, segment.position.1),
(segment.cp1.0, segment.cp1.1),
(segment.cp2.0, segment.cp2.1)
));
Box::new(preamble.into_iter()
.chain(curves)
.chain(iter::once(Draw::Stroke)))
}
}