Skip to main content

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}