tessera_ui_basic_components/pipelines/image_vector/
command.rs

1use std::{
2    hash::{Hash, Hasher},
3    sync::Arc,
4};
5
6use tessera_ui::{Color, DrawCommand};
7
8/// Vertex attributes for tessellated vector geometry.
9#[repr(C)]
10#[derive(Clone, Copy, Debug, bytemuck::Pod, bytemuck::Zeroable)]
11pub struct ImageVectorVertex {
12    /// 2D position in normalized SVG viewport coordinates.
13    pub position: [f32; 2],
14    /// Premultiplied color for the vertex.
15    pub color: Color,
16}
17
18/// Tessellated vector data ready for rendering.
19#[derive(Debug, Clone)]
20pub struct ImageVectorData {
21    /// Width of the original SVG viewport.
22    pub viewport_width: f32,
23    /// Height of the original SVG viewport.
24    pub viewport_height: f32,
25    /// Vertex data (positions and colors).
26    pub vertices: Arc<Vec<ImageVectorVertex>>,
27    /// Triangle indices referencing `vertices`.
28    pub indices: Arc<Vec<u32>>,
29}
30
31impl ImageVectorData {
32    /// Creates vector data from raw vertices and indices.
33    pub fn new(
34        viewport_width: f32,
35        viewport_height: f32,
36        vertices: Arc<Vec<ImageVectorVertex>>,
37        indices: Arc<Vec<u32>>,
38    ) -> Self {
39        Self {
40            viewport_width,
41            viewport_height,
42            vertices,
43            indices,
44        }
45    }
46}
47
48impl PartialEq for ImageVectorData {
49    fn eq(&self, other: &Self) -> bool {
50        self.viewport_width.to_bits() == other.viewport_width.to_bits()
51            && self.viewport_height.to_bits() == other.viewport_height.to_bits()
52            && Arc::ptr_eq(&self.vertices, &other.vertices)
53            && Arc::ptr_eq(&self.indices, &other.indices)
54    }
55}
56
57impl Eq for ImageVectorData {}
58
59impl Hash for ImageVectorData {
60    fn hash<H: Hasher>(&self, state: &mut H) {
61        state.write_u32(self.viewport_width.to_bits());
62        state.write_u32(self.viewport_height.to_bits());
63        state.write_usize(Arc::as_ptr(&self.vertices) as usize);
64        state.write_usize(Arc::as_ptr(&self.indices) as usize);
65    }
66}
67
68/// Defines how the tint color is combined with the vector image.
69#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
70pub enum VectorTintMode {
71    /// Multiplies the tint color with the image color.
72    /// This is the default behavior.
73    /// Result = Image * Tint
74    #[default]
75    Multiply,
76    /// Ignores the image's color channels, using only its alpha to mask the tint color.
77    /// Result = Tint * Image.Alpha
78    Solid,
79}
80
81/// Draw command for vector images.
82#[derive(Debug, Clone, PartialEq)]
83pub struct ImageVectorCommand {
84    /// Shared vector mesh data.
85    pub data: Arc<ImageVectorData>,
86    /// Tint color multiplied with the mesh.
87    pub tint: Color,
88    /// How to apply the tint.
89    pub tint_mode: VectorTintMode,
90    /// Rotation in degrees.
91    pub rotation: f32,
92}
93
94impl DrawCommand for ImageVectorCommand {}