summaryrefslogtreecommitdiffstats
path: root/core/src/rendering.rs
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/rendering.rs')
-rw-r--r--core/src/rendering.rs86
1 files changed, 86 insertions, 0 deletions
diff --git a/core/src/rendering.rs b/core/src/rendering.rs
new file mode 100644
index 0000000..f7a0189
--- /dev/null
+++ b/core/src/rendering.rs
@@ -0,0 +1,86 @@
1use super::core_shapes::*;
2use super::styles::{DefinedDashStyle, DefinedStrokeStyle, FillStyle, Pattern};
3use super::text::{DefinedFontDescription, FontDescription};
4use super::types::DefinedShapeContext;
5
6pub trait Renderer {
7 fn move_to(&mut self, x: f64, y: f64);
8 fn stroke(&mut self);
9 fn fill(&mut self);
10 fn fill_preserve(&mut self);
11 fn set_pattern(&mut self, pattern: &Pattern);
12 fn set_dash(&mut self, dash: &DefinedDashStyle);
13 fn clear_dash(&mut self);
14 fn set_line_width(&mut self, width: f64);
15 fn line_to(&mut self, x: f64, y: f64);
16 fn rectangle(&mut self, x: f64, y: f64, width: f64, height: f64);
17 // For a font of size 1.
18 fn text_extents(&self, text: &str, font: &FontDescription) -> (f64, f64);
19 fn show_text(&mut self, text: &str, font: &DefinedFontDescription);
20}
21
22pub trait Render {
23 fn render(&self, context: DefinedShapeContext, renderer: &mut dyn Renderer);
24}
25
26fn draw(fill: &FillStyle, stroke: &DefinedStrokeStyle, renderer: &mut dyn Renderer) {
27 let stroking = !stroke.pattern.is_none();
28
29 if !fill.pattern.is_none() {
30 renderer.set_pattern(&fill.pattern);
31 if stroking {
32 renderer.fill_preserve();
33 } else {
34 renderer.fill();
35 }
36 }
37
38 if !stroke.pattern.is_none() {
39 renderer.set_pattern(&stroke.pattern);
40 renderer.set_line_width(stroke.line_width);
41 if let Some(dash) = &stroke.dash {
42 renderer.set_dash(dash);
43 }
44 renderer.stroke();
45 renderer.clear_dash();
46 }
47}
48
49impl Render for Rectangle {
50 fn render(&self, context: DefinedShapeContext, renderer: &mut dyn Renderer) {
51 let bounds = &context.bounds;
52 renderer.rectangle(bounds.left, bounds.top, bounds.width, bounds.height);
53 draw(&context.fill, &context.stroke, renderer);
54 }
55}
56
57impl Render for DefinedText {
58 fn render(&self, context: DefinedShapeContext, renderer: &mut dyn Renderer) {
59 // TODO: select font, style, text shaping (renderer specific), etc.
60 let bounds = &context.bounds;
61 //renderer.move_to(bounds.left, bounds.top + self.font.size);
62 renderer.move_to(bounds.left, bounds.top);
63 // TODO: ???
64 //draw(&context.fill, &context.stroke, renderer);
65 renderer.show_text(&self.content, &self.font);
66 }
67}
68
69impl Render for DefinedStraightPath {
70 fn render(&self, context: DefinedShapeContext, renderer: &mut dyn Renderer) {
71 let mut iter = self.points.iter();
72
73 let first_point = match iter.next() {
74 Some(point) => point,
75 None => return,
76 };
77
78 renderer.move_to(first_point.x, first_point.y);
79
80 for point in iter {
81 renderer.line_to(point.x, point.y);
82 }
83
84 draw(&context.fill, &context.stroke, renderer);
85 }
86}