1#[cfg(feature = "internal")]
2use lotus_script_sys::FfiObject;
3
4pub use lotus_shared::graphics::*;
5
6pub mod textures {
7 use lotus_script_sys::FfiObject;
8 use lotus_shared::{
9 content::ContentId,
10 graphics::Color,
11 math::{IVec2, Rectangle, UVec2},
12 };
13
14 pub use lotus_shared::graphics::textures::*;
15
16 #[derive(Debug)]
18 pub struct Texture(TextureHandle);
19
20 impl Texture {
21 #[must_use]
23 pub fn create<'a>(options: impl Into<TextureCreationOptions<'a>>) -> Self {
24 let options = options.into();
25 let options = FfiObject::new(&options);
26
27 unsafe {
28 Self(TextureHandle::new(lotus_script_sys::textures::create(
29 options.packed(),
30 )))
31 }
32 }
33
34 pub fn add_action(&mut self, action: TextureAction) {
37 let action = FfiObject::new(&action);
38
39 unsafe { lotus_script_sys::textures::add_action(self.0.id(), action.packed()) }
40 }
41
42 pub fn draw_rect(&mut self, start: impl Into<UVec2>, end: impl Into<UVec2>, color: Color) {
44 self.add_action(TextureAction::DrawRect {
45 start: start.into(),
46 end: end.into(),
47 color,
48 });
49 }
50
51 pub fn clear(&mut self, color: Color) {
53 self.add_action(TextureAction::Clear(color));
54 }
55
56 #[inline]
58 pub fn read_pixel(&self, x: u32, y: u32) -> Color {
59 let packed = unsafe { lotus_script_sys::textures::get_pixel(self.0.id(), x, y) };
60 packed.into()
61 }
62
63 pub fn draw_pixels<P>(&mut self, pixels: &[P])
65 where
66 P: Into<DrawPixel> + Copy,
67 {
68 let pixels = pixels.iter().map(|p| (*p).into()).collect();
69
70 self.add_action(TextureAction::DrawPixels(pixels));
71 }
72
73 pub fn draw_texture(&mut self, other: &Texture, options: DrawTextureOpts) {
75 self.add_action(TextureAction::DrawScriptTexture {
76 handle: other.handle(),
77 options,
78 });
79 }
80
81 pub fn apply_to(&mut self, name: &str) {
83 let name = FfiObject::new(&name);
84 unsafe { lotus_script_sys::textures::apply_to(self.0.id(), name.packed()) }
85 }
86
87 pub fn flush(&mut self) -> bool {
91 unsafe { lotus_script_sys::textures::flush_actions(self.0.id()) == 1 }
92 }
93
94 pub fn draw_script_texture(&mut self, other: &Texture, options: DrawTextureOpts) {
96 self.add_action(TextureAction::DrawScriptTexture {
97 handle: other.handle(),
98 options,
99 });
100 }
101
102 #[expect(clippy::too_many_arguments)]
104 pub fn draw_text(
105 &mut self,
106 font: ContentId,
107 text: impl Into<String>,
108 top_left: impl Into<IVec2>,
109 letter_spacing: u32,
110 full_color: impl Into<Option<Color>>,
111 alpha_mode: AlphaMode,
112 target_rect: impl Into<Option<Rectangle>>,
113 ) {
114 self.add_action(TextureAction::DrawText {
115 font,
116 text: text.into(),
117 top_left: top_left.into(),
118 letter_spacing,
119 full_color: full_color.into(),
120 alpha_mode,
121 target_rect: target_rect.into(),
122 });
123 }
124
125 pub fn handle(&self) -> TextureHandle {
127 self.0
128 }
129
130 pub fn forget(mut self) {
133 self.0 = TextureHandle::new(u32::MAX);
134 }
135
136 pub fn expose(&self, name: &str) {
138 let name = FfiObject::new(&name);
139 unsafe { lotus_script_sys::textures::expose(self.0.id(), name.packed()) }
140 }
141 }
142
143 impl Drop for Texture {
144 fn drop(&mut self) {
145 if self.0.id() != u32::MAX {
146 unsafe { lotus_script_sys::textures::dispose(self.0.id()) }
147 }
148 }
149 }
150
151 pub enum DrawableTexture {
152 Script(TextureHandle),
155 }
156
157 impl From<&Texture> for DrawableTexture {
158 fn from(texture: &Texture) -> Self {
159 Self::Script(texture.handle())
160 }
161 }
162
163 impl From<TextureHandle> for DrawableTexture {
164 fn from(handle: TextureHandle) -> Self {
165 Self::Script(handle)
166 }
167 }
168}
169
170#[cfg(feature = "internal")]
171pub fn fetch_drawable_texture_properties() -> Vec<DrawableTextureProperties> {
172 let properties = unsafe { lotus_script_sys::textures::fetch_drawable_texture_properties() };
173 FfiObject::from_packed(properties).deserialize()
174}