euv_chart/geom/base/struct.rs
1use super::*;
2
3/// A two-dimensional affine transform stored as the six meaningful entries
4/// of a 3×3 matrix.
5///
6/// The matrix is applied to a point `(x, y)` as:
7///
8/// ```text
9/// x' = a·x + c·y + e
10/// y' = b·x + d·y + f
11/// ```
12///
13/// This is the same layout SVG and Canvas2D use, so a transform built here
14/// can be handed to a Canvas2D context verbatim.
15#[derive(Clone, Copy, Debug, lombok_macros::Data, PartialEq)]
16pub struct Transform2D {
17 /// The horizontal scale / shear term applied to `x`.
18 #[get(type(copy))]
19 pub a: f64,
20 /// The vertical shear term applied to `x`.
21 #[get(type(copy))]
22 pub b: f64,
23 /// The horizontal shear term applied to `y`.
24 #[get(type(copy))]
25 pub c: f64,
26 /// The vertical scale / shear term applied to `y`.
27 #[get(type(copy))]
28 pub d: f64,
29 /// The horizontal translation.
30 #[get(type(copy))]
31 pub e: f64,
32 /// The vertical translation.
33 #[get(type(copy))]
34 pub f: f64,
35}
36
37/// An axis-aligned bounding box, stored as its minimum corner plus its
38/// extent.
39///
40/// The `min` / `max` form (rather than `x` / `y` / `width` / `height`)
41/// keeps the empty-box case representable: a box that has not been
42/// extended yet is `min > max` on every axis, which is the standard
43/// sentinel for "no geometry yet".
44#[derive(Clone, Copy, Debug, lombok_macros::Data, PartialEq)]
45pub struct BBox {
46 /// The smallest `x` reached by the geometry.
47 #[get(type(copy))]
48 pub min_x: f64,
49 /// The smallest `y` reached by the geometry.
50 #[get(type(copy))]
51 pub min_y: f64,
52 /// The largest `x` reached by the geometry.
53 #[get(type(copy))]
54 pub max_x: f64,
55 /// The largest `y` reached by the geometry.
56 #[get(type(copy))]
57 pub max_y: f64,
58}
59
60/// A point in path space.
61///
62/// Paths are stored in 32-bit floats: they are consumed by the GPU
63/// backends, which upload them verbatim, and pixel-space coordinates never
64/// need more than 24 bits of mantissa. Layout arithmetic happens in
65/// `f64` and is narrowed once, when a path is built.
66#[derive(Clone, Copy, Debug, Default, lombok_macros::Data, PartialEq)]
67pub struct Point {
68 /// The horizontal coordinate.
69 #[get(type(copy))]
70 pub x: f32,
71 /// The vertical coordinate.
72 #[get(type(copy))]
73 pub y: f32,
74}
75
76/// A closed polygon: a flat list of points plus an explicit count.
77///
78/// The flat representation keeps the hot triangulation loop free of
79/// indirection: the inner scan reads `points[i]` directly instead of
80/// chasing a per-vertex pointer.
81#[derive(Clone, Debug, Default, lombok_macros::Data, PartialEq)]
82pub struct Polygon {
83 /// The vertices, in order.
84 pub points: Vec<Point>,
85}
86
87/// A sequence of drawing commands describing one or more sub-paths.
88///
89/// A path is the unit of geometry in the chart renderer: axes, series
90/// polylines, pie slices, radar rings, and text decorations are all
91/// expressed as paths. Paths are immutable once built — the builder
92/// produces the final command buffer, and the tessellator consumes it
93/// without mutating it.
94#[derive(Clone, Debug, Default, lombok_macros::Data, PartialEq)]
95pub struct Path {
96 /// The command buffer.
97 #[get(pub(crate))]
98 #[get_mut(pub(crate))]
99 #[set(pub(crate))]
100 pub(crate) commands: Vec<PathCommand>,
101 /// The rule used to decide which parts of the path are inside it.
102 #[get(pub(crate), type(copy))]
103 #[get_mut(pub(crate))]
104 #[set(pub(crate))]
105 pub(crate) fill_rule: FillRule,
106}
107
108/// A fluent builder for [`Path`].
109///
110/// Every method returns `Self` so a path can be assembled in one
111/// expression without a mutable borrow in the middle of a call chain.
112#[derive(Clone, Debug, lombok_macros::Data)]
113pub struct PathBuilder {
114 /// The commands of the path under construction.
115 #[get(pub(crate))]
116 #[get_mut(pub(crate))]
117 #[set(pub(crate))]
118 pub(crate) commands: Vec<PathCommand>,
119 /// The rule the finished path is filled with.
120 #[get(pub(crate), type(copy))]
121 #[get_mut(pub(crate))]
122 #[set(pub(crate))]
123 pub(crate) fill_rule: FillRule,
124 /// The point the path is currently at.
125 #[get(pub(crate), type(copy))]
126 #[get_mut(pub(crate))]
127 #[set(pub(crate))]
128 pub(crate) current: Point,
129 /// The point the current sub-path started at.
130 #[get(pub(crate), type(copy))]
131 #[get_mut(pub(crate))]
132 #[set(pub(crate))]
133 pub(crate) start: Point,
134}
135
136/// An ellipse: the shape an arc is cut out of.
137///
138/// The type stays inside the crate: it gathers the four numbers an arc
139/// needs, so that the function that cuts the arc does not take eight
140/// of them.
141#[derive(Clone, Copy, Debug, PartialEq)]
142pub(crate) struct Ellipse {
143 /// The horizontal position of the centre.
144 pub(crate) center_x: f64,
145 /// The vertical position of the centre.
146 pub(crate) center_y: f64,
147 /// The radius along the horizontal axis.
148 pub(crate) radius_x: f64,
149 /// The radius along the vertical axis.
150 pub(crate) radius_y: f64,
151}
152
153/// The geometric parameters of a stroke.
154///
155/// The colour lives in the paint layer; this struct carries only what the
156/// tessellator needs to turn a path into stroke geometry.
157#[derive(Clone, Debug, lombok_macros::Data, PartialEq)]
158pub struct StrokeStyle {
159 /// The line width, in pixels.
160 #[get(type(copy))]
161 pub width: f32,
162 /// How the ends of an open stroke are drawn.
163 #[get(type(copy))]
164 pub cap: LineCap,
165 /// How the corners between segments are drawn.
166 #[get(type(copy))]
167 pub join: LineJoin,
168 /// The dash pattern applied along the stroke.
169 pub dash: DashPattern,
170}
171
172/// A dash pattern applied to a stroke.
173///
174/// `offset` shifts the pattern along the path; a negative offset moves the
175/// pattern backwards.
176#[derive(Clone, Debug, Default, lombok_macros::Data, PartialEq)]
177pub struct DashPattern {
178 /// The alternating on/off lengths, in pixels.
179 ///
180 /// An empty slice means "solid". An odd-length array is repeated twice
181 /// to make the on/off alternation well-defined.
182 pub pattern: Vec<f32>,
183 /// The distance into the pattern at which the dash starts.
184 #[get(type(copy))]
185 pub offset: f32,
186}