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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
//! **dessin** is library aimed at building complex drawings, combine them, move them and export them as PDF or SVG.
//!
//! Details about the [macro][`crate::macros`].
//!
//! ## Example
//!
//! ```
//! use dessin::prelude::*;
//! use palette::{named, Srgb};
//!
//! #[derive(Default, Shape)]
//! struct MyShape {
//! text: String,
//! }
//! impl MyShape {
//! fn say_this(&mut self, what: &str) {
//! self.text = format!("{} And check this out: `{what}`", self.text);
//! }
//! }
//! impl From<MyShape> for Shape {
//! fn from(MyShape { text }: MyShape) -> Self {
//! dessin!(*Text(fill = Srgb::<f32>::from_format(named::RED).into_linear(), { text })).into()
//! }
//! }
//!
//! fn main() {
//! let dessin = dessin!(for x in 0..10 {
//! let radius = x as f32 * 10.;
//!
//! dessin!([
//! *Circle(
//! fill = Srgb::<f32>::from_format(named::RED).into_linear(),
//! { radius },
//! translate = [x as f32 * 5., 10.],
//! ),
//! *Text(fill = Srgb::<f32>::from_format(named::BLACK).into_linear(), font_size = 10., text = "Hi !",),
//! ])
//! });
//!
//! let dessin = dessin!([
//! { dessin }(scale = [2., 2.]),
//! MyShape(say_this = "Hello world"),
//! ]);
//! }
//! ```
//!
//! ## Components
//!
//! [Base components][`crate::shapes`] are defined in the `shapes` module.
//!
//! [Components using base ones][`crate::contrib`] are defined in the `contrib` module.
//!
//! In `dessin`, a component is just a struct/enum that can be converted to a [Shape][crate::shapes::Shape],
//! and implements the [Default][`std::default::Default`] trait.
//!
//! This means that a component can be as simple as:
//! ```
//! use dessin::prelude::*;
//!
//! #[derive(Default)]
//! struct MyComponent {}
//!
//! impl From<MyComponent> for Shape {
//! fn from(my_component: MyComponent) -> Shape {
//! dessin!(
//! // Implementation...
//! )
//! }
//! }
//! ```
//!
//! Since the [dessin!][`dessin_macros::dessin`] macro is only syntactic sugar for creating a [Shape][crate::shapes::Shape],
//! all parameters are simply rust function with the following signature: `fn (&mut self, argument_value: ArgumentType) {...}`.
//!
//! It can be tedious to create these function for all parameters, so the derive macro [Shape][`dessin_macro::shape`]
//! is here to do exactly that.
//!
//! So
//! ```
//! # use nalgebra::Transform2;
//! # use dessin::prelude::*;
//! # pub trait ShapeOp {}
//! # #[derive(Clone)]
//! #[derive(Default, Shape)]
//! struct MyComponent {
//! // This auto implements ShapeOp for MyComponent using `my_local_transform` as the storage.
//! #[local_transform]
//! my_local_transform: Transform2<f32>,
//!
//! // Generate a function for u32
//! value: u32,
//!
//! // Does not generate a function for this field
//! #[shape(skip)]
//! skip_value: u32,
//!
//! // Generates a function for Into<u32>
//! #[shape(into)]
//! into_value: u32,
//!
//! // Generates a function that does not take any arguments, but set `my_bool` to true
//! #[shape(bool)]
//! my_bool: bool,
//! }
//!
//! # impl From<MyComponent> for Shape {
//! # fn from(_: MyComponent) -> Shape { unimplemented!() }
//! # }
//! ```
//!
//! becomes
//! ```
//! # use nalgebra::Transform2;
//! # use dessin::prelude::*;
//! # pub trait ShapeOp {}
//!
//! #[derive(Default)]
//! struct MyComponent {
//! my_local_transform: Transform2<f32>,
//! value: u32,
//! skip_value: u32,
//! into_value: u32,
//! my_bool: bool,
//! }
//!
//! impl ShapeOp for MyComponent { /* skip impl */ }
//!
//! impl MyComponent {
//! pub fn value(&mut self, value: u32) -> &mut Self {
//! # self
//! /* skip impl */
//! }
//! pub fn into_value<T: Into<u32>>(&mut self, value: T) -> &mut Self {
//! # self
//! /* skip impl */
//! }
//! pub fn my_bool(&mut self) -> &mut Self {
//! # self
//! /* skip impl */
//! }
//! }
//!
//! # impl From<MyComponent> for Shape {
//! # fn from(_: MyComponent) -> Shape { unimplemented!() }
//! # }
//! ```
//! To be precise, all functions generated by this derive macro, return `&mut Self` to chain function together.
//! Generated functions have the same name as their corresponding field.
//! This derive macro also generate corresponding `with_xxxx`, taking `self` instead of `&mut self` and returning `Self`.
//!
//! One still does need to implement `From<MyComponent> for Shape { ... }` manually.
//!
//! ## Implement own export format.
//! Documentation can be found in the [`export`] module.
// We need this in order for the proc_macro to work in this library.
// See https://github.com/rust-lang/rust/issues/56409 for more details
extern crate self as dessin;
/// Shapes made of basic [shapes][crate::shapes::Shape]
/// Declarations to create an export format.
/// Building blocks of a dessin
/// Styling of the building blocks
pub use image;
pub use nalgebra;
pub use palette;
/// Prelude module includes everyting you need to build a dessin.
/// You can of courses cherry pick what you need by importing directly from other modules.
/// Everything related to fonts.