1use std::rc::Rc;
2
3pub use cranpose_render_common::graph_scene::{HitRegion, Scene};
4use cranpose_render_common::primitive_emit::ShapeDrawParams;
5use cranpose_ui::TextStyle;
6use cranpose_ui_graphics::{
7 ArcGeometry, BlendMode, Brush, Color, ColorFilter, ImageBitmap, ImageSampling, LineGeometry,
8 Point, Rect, RoundedCornerShape, Stroke,
9};
10
11#[derive(Clone)]
12pub(crate) struct DrawShape {
13 pub rect: Rect,
14 pub snap_anchor: Option<Point>,
15 pub snap_to_pixel_grid: bool,
16 pub brush: Brush,
17 pub shape: Option<RoundedCornerShape>,
18 pub stroke: Option<Stroke>,
19 pub arc: Option<ArcGeometry>,
20 pub line: Option<LineGeometry>,
21 pub z_index: usize,
22 pub clip: Option<Rect>,
23 pub blend_mode: BlendMode,
24}
25
26#[derive(Clone)]
27pub(crate) struct TextDraw {
28 pub rect: Rect,
29 pub snap_anchor: Option<Point>,
30 pub text: Rc<cranpose_ui::text::AnnotatedString>,
31 pub color: Color,
32 pub text_style: TextStyle,
33 pub font_size: f32,
34 pub scale: f32,
35 pub z_index: usize,
36 pub clip: Option<Rect>,
37}
38
39#[derive(Clone)]
40pub(crate) struct ImageDraw {
41 pub rect: Rect,
42 pub snap_anchor: Option<Point>,
43 pub image: ImageBitmap,
44 pub alpha: f32,
45 pub color_filter: Option<ColorFilter>,
46 pub sampling: ImageSampling,
47 pub z_index: usize,
48 pub clip: Option<Rect>,
49 pub blend_mode: BlendMode,
50 pub src_rect: Option<Rect>,
51}
52
53pub(crate) struct RasterScene {
54 pub shapes: Vec<DrawShape>,
55 pub images: Vec<ImageDraw>,
56 pub texts: Vec<TextDraw>,
57 pub next_z: usize,
58}
59
60impl RasterScene {
61 pub fn new() -> Self {
62 Self {
63 shapes: Vec::new(),
64 images: Vec::new(),
65 texts: Vec::new(),
66 next_z: 0,
67 }
68 }
69
70 pub fn push_shape(
71 &mut self,
72 rect: Rect,
73 brush: Brush,
74 shape: Option<RoundedCornerShape>,
75 clip: Option<Rect>,
76 blend_mode: BlendMode,
77 ) {
78 let z_index = self.next_z;
79 self.next_z += 1;
80 self.shapes.push(DrawShape {
81 rect,
82 snap_anchor: None,
83 snap_to_pixel_grid: false,
84 brush,
85 shape,
86 stroke: None,
87 arc: None,
88 line: None,
89 z_index,
90 clip,
91 blend_mode,
92 });
93 }
94
95 pub fn push_pixel_snapped_shape(
96 &mut self,
97 rect: Rect,
98 brush: Brush,
99 shape: Option<RoundedCornerShape>,
100 clip: Option<Rect>,
101 blend_mode: BlendMode,
102 ) {
103 let z_index = self.next_z;
104 self.next_z += 1;
105 self.shapes.push(DrawShape {
106 rect,
107 snap_anchor: None,
108 snap_to_pixel_grid: true,
109 brush,
110 shape,
111 stroke: None,
112 arc: None,
113 line: None,
114 z_index,
115 clip,
116 blend_mode,
117 });
118 }
119
120 pub fn push_shape_params(&mut self, params: ShapeDrawParams) {
123 let z_index = self.next_z;
124 self.next_z += 1;
125 self.shapes.push(DrawShape {
126 rect: params.rect,
127 snap_anchor: None,
128 snap_to_pixel_grid: false,
129 brush: params.brush.into_brush(),
130 shape: params.shape,
131 stroke: params.stroke,
132 arc: params.arc,
133 line: params.line,
134 z_index,
135 clip: params.clip,
136 blend_mode: params.blend_mode,
137 });
138 }
139
140 #[expect(clippy::too_many_arguments)]
141 pub fn push_image_with_geometry(
142 &mut self,
143 rect: Rect,
144 _local_rect: Rect,
145 _quad: [[f32; 2]; 4],
146 image: ImageBitmap,
147 alpha: f32,
148 color_filter: Option<ColorFilter>,
149 sampling: ImageSampling,
150 clip: Option<Rect>,
151 src_rect: Option<Rect>,
152 blend_mode: BlendMode,
153 ) {
154 let z_index = self.next_z;
155 self.next_z += 1;
156 self.images.push(ImageDraw {
157 rect,
158 snap_anchor: None,
159 image,
160 alpha: alpha.clamp(0.0, 1.0),
161 color_filter,
162 sampling,
163 z_index,
164 clip,
165 blend_mode,
166 src_rect,
167 });
168 }
169
170 #[expect(clippy::too_many_arguments)]
171 pub fn push_text(
172 &mut self,
173 rect: Rect,
174 text: Rc<cranpose_ui::text::AnnotatedString>,
175 color: Color,
176 text_style: TextStyle,
177 font_size: f32,
178 scale: f32,
179 clip: Option<Rect>,
180 ) {
181 let z_index = self.next_z;
182 self.next_z += 1;
183 self.texts.push(TextDraw {
184 rect,
185 snap_anchor: None,
186 text,
187 color,
188 text_style,
189 font_size,
190 scale,
191 z_index,
192 clip,
193 });
194 }
195}
196
197impl Default for RasterScene {
198 fn default() -> Self {
199 Self::new()
200 }
201}