lotus_script/graphics.rs
1//! Zeichen- und Textur-API für Script-Displays.
2//!
3//! Drawing and texture API for script displays.
4
5#[cfg(feature = "internal")]
6use lotus_script_sys::FfiObject;
7
8pub use lotus_shared::graphics::*;
9
10pub mod textures {
11 //! Erstellung und Bearbeitung von Script-Texturen.
12 //!
13 //! Creation and manipulation of script textures.
14
15 use lotus_script_sys::FfiObject;
16 use lotus_shared::{
17 content::ContentId,
18 graphics::Color,
19 math::{IVec2, Rectangle, UVec2},
20 };
21
22 pub use lotus_shared::graphics::textures::*;
23
24 /// Textur, die bearbeitet und auf Script-Textur-Slots angezeigt werden kann.
25 ///
26 /// A texture that can be manipulated and displayed on script texture slots.
27 #[derive(Debug)]
28 pub struct Texture(TextureHandle);
29
30 impl Texture {
31 /// Erstellt eine neue Script-Textur.
32 ///
33 /// Creates a new script texture.
34 #[must_use]
35 pub fn create<'a>(options: impl Into<TextureCreationOptions<'a>>) -> Self {
36 let options = options.into();
37 let options = FfiObject::new(&options);
38
39 unsafe {
40 Self(TextureHandle::new(lotus_script_sys::textures::create(
41 options.packed(),
42 )))
43 }
44 }
45
46 /// Fügt eine Zeichenaktion zur Textur hinzu.
47 /// Bevorzugt die Hilfsmethoden statt direktem Aufruf.
48 ///
49 /// Adds a drawing action to the texture.
50 /// Prefer the helper methods over calling this directly.
51 pub fn add_action(&mut self, action: TextureAction) {
52 let action = FfiObject::new(&action);
53
54 unsafe { lotus_script_sys::textures::add_action(self.0.id(), action.packed()) }
55 }
56
57 /// Zeichnet ein Rechteck auf die Textur.
58 ///
59 /// Draws a rectangle on the texture.
60 pub fn draw_rect(&mut self, start: impl Into<UVec2>, end: impl Into<UVec2>, color: Color) {
61 self.add_action(TextureAction::DrawRect {
62 start: start.into(),
63 end: end.into(),
64 color,
65 });
66 }
67
68 /// Füllt die Textur mit einer Farbe.
69 ///
70 /// Clears the texture with a color.
71 pub fn clear(&mut self, color: Color) {
72 self.add_action(TextureAction::Clear(color));
73 }
74
75 /// Liest die Farbe eines Pixels auf der Textur.
76 ///
77 /// Reads the color of a pixel on the texture.
78 #[inline]
79 pub fn read_pixel(&self, x: u32, y: u32) -> Color {
80 let packed = unsafe { lotus_script_sys::textures::get_pixel(self.0.id(), x, y) };
81 packed.into()
82 }
83
84 /// Zeichnet mehrere Pixel auf die Textur.
85 ///
86 /// Draws multiple pixels on the texture.
87 pub fn draw_pixels<P>(&mut self, pixels: &[P])
88 where
89 P: Into<DrawPixel> + Copy,
90 {
91 let pixels = pixels.iter().map(|p| (*p).into()).collect();
92
93 self.add_action(TextureAction::DrawPixels(pixels));
94 }
95
96 /// Zeichnet eine andere Textur über diese.
97 ///
98 /// Draws another texture on top of this one.
99 pub fn draw_texture(&mut self, other: &Texture, options: DrawTextureOpts) {
100 self.add_action(TextureAction::DrawScriptTexture {
101 handle: other.handle(),
102 options,
103 });
104 }
105
106 /// Wendet die Textur auf einen benannten Spiel-Textur-Slot an (Name im Content-Tool).
107 /// Einmal pro Ziel-Slot aufrufen.
108 ///
109 /// Applies the texture to a named in-game texture slot (name defined in the content tool).
110 /// Call once per target slot.
111 pub fn apply_to(&mut self, name: &str) {
112 let name = FfiObject::new(&name);
113 unsafe { lotus_script_sys::textures::apply_to(self.0.id(), name.packed()) }
114 }
115
116 /// Wendet ausstehende Aktionen sofort an.
117 /// Kann `false` liefern, solange Assets noch streamen — erneut aufrufen, bis `true`.
118 ///
119 /// Applies pending actions immediately.
120 /// May return `false` while assets are still streaming; call again until `true`.
121 pub fn flush(&mut self) -> bool {
122 unsafe { lotus_script_sys::textures::flush_actions(self.0.id()) == 1 }
123 }
124
125 /// Zeichnet eine andere Script-Textur über diese.
126 ///
127 /// Draws another script texture on top of this one.
128 pub fn draw_script_texture(&mut self, other: &Texture, options: DrawTextureOpts) {
129 self.add_action(TextureAction::DrawScriptTexture {
130 handle: other.handle(),
131 options,
132 });
133 }
134
135 /// Zeichnet Text auf die Textur.
136 ///
137 /// Draws text on the texture.
138 #[expect(clippy::too_many_arguments)]
139 pub fn draw_text(
140 &mut self,
141 font: ContentId,
142 text: impl Into<String>,
143 top_left: impl Into<IVec2>,
144 letter_spacing: u32,
145 full_color: impl Into<Option<Color>>,
146 alpha_mode: AlphaMode,
147 target_rect: impl Into<Option<Rectangle>>,
148 ) {
149 self.add_action(TextureAction::DrawText {
150 font,
151 text: text.into(),
152 top_left: top_left.into(),
153 letter_spacing,
154 full_color: full_color.into(),
155 alpha_mode,
156 target_rect: target_rect.into(),
157 });
158 }
159
160 /// Gibt den Handle der Textur zurück.
161 ///
162 /// Returns the handle of the texture.
163 pub fn handle(&self) -> TextureHandle {
164 self.0
165 }
166
167 /// Verhindert das Freigeben beim Drop — Textur bleibt ohne Referenz bestehen.
168 /// Nur verwenden, wenn die Textur absichtlich ohne Handle weiterleben soll.
169 ///
170 /// Prevents disposal on drop so the texture outlives this handle.
171 /// Use only when the texture should stay alive without a reference.
172 pub fn forget(mut self) {
173 self.0 = TextureHandle::new(u32::MAX);
174 }
175
176 /// Stellt die Textur unter dem angegebenen Namen für die Plugin-API bereit.
177 ///
178 /// Exposes the texture to the plugin API under the given name.
179 pub fn expose(&self, name: &str) {
180 let name = FfiObject::new(&name);
181 unsafe { lotus_script_sys::textures::expose(self.0.id(), name.packed()) }
182 }
183 }
184
185 impl Drop for Texture {
186 fn drop(&mut self) {
187 if self.0.id() != u32::MAX {
188 unsafe { lotus_script_sys::textures::dispose(self.0.id()) }
189 }
190 }
191 }
192
193 /// Zeichenbare Textur aus Script-Handle oder (künftig) Content-ID.
194 ///
195 /// Drawable texture from a script handle or (future) content id.
196 pub enum DrawableTexture {
197 // TODO: Support content textures.
198 // Content(ContentId),
199 /// Script-Textur-Handle.
200 ///
201 /// Script texture handle.
202 Script(TextureHandle),
203 }
204
205 impl From<&Texture> for DrawableTexture {
206 fn from(texture: &Texture) -> Self {
207 Self::Script(texture.handle())
208 }
209 }
210
211 impl From<TextureHandle> for DrawableTexture {
212 fn from(handle: TextureHandle) -> Self {
213 Self::Script(handle)
214 }
215 }
216}
217
218/// Liest Eigenschaften aller zeichenbaren Textur-Slots aus dem Content-Tool.
219///
220/// Fetches properties of all drawable texture slots from the content tool.
221#[cfg(feature = "internal")]
222pub fn fetch_drawable_texture_properties() -> Vec<DrawableTextureProperties> {
223 let properties = unsafe { lotus_script_sys::textures::fetch_drawable_texture_properties() };
224 FfiObject::from_packed(properties).deserialize()
225}