1#![allow(unused)]
2
3pub use crate::camera::camera2d::Camera2D;
6pub use crate::camera::render_target::RenderTarget;
7use crate::draw_state::shapes::Shape;
8pub use crate::draw_state::shapes::color::*;
9pub use crate::end_frame;
10use crate::global::{PENDING_CONFIG, STATE, ctx};
11pub use crate::misc::flake_image::Image;
12use crate::misc::font::Font;
13pub use crate::misc::math::*;
14pub use crate::misc::rect::Rect;
15use crate::misc::span::RichtextSection;
16pub use crate::misc::span::Span;
17pub use crate::misc::timer::Timer;
18pub use crate::misc::*;
19use crate::model::instance::Instance;
20pub use crate::model::texture::DrawTextureParams;
21pub use crate::model::texture::FilterType;
22use crate::model::texture::{GpuTexture, Texture};
23pub use crate::runtime::next_frame::next_frame;
24pub use crate::{FlakeResult, flake};
25use image::{DynamicImage, GenericImageView, ImageBuffer, Rgb, Rgba};
26use std::borrow::Borrow;
27use std::sync::{Arc, Mutex};
28use wgpu::{CommandEncoder, Device, Queue, SurfaceConfiguration, TextureView};
29pub use winit::event::MouseButton;
30pub use winit::event::WindowEvent;
31pub use winit::keyboard::KeyCode;
32#[cfg(target_os = "windows")]
33use winit::platform::windows::WindowExtWindows;
34use winit::window::Window;
35pub use winit::window::{CursorIcon, WindowButtons, WindowLevel};
36pub fn flake_quit() {
46 ctx(|s| s.exit())
47}
48
49pub fn flake_sleep(seconds: f32) {
60 std::thread::sleep(std::time::Duration::from_secs_f32(seconds));
61}
62
63pub fn add_timer(timer: Timer) -> Timer {
75 if STATE.get().is_some() {
76 return ctx(|s| {
77 if !s.timers.contains(&timer) {
78 s.add_timer(timer.clone());
79 }
80 timer
81 });
82 }
83
84 PENDING_CONFIG.with_borrow_mut(|s| {
85 if !s.timers.contains(&timer) {
86 s.timers.push(timer.clone())
87 }
88 });
89
90 timer
91}
92
93pub fn get_window() -> Arc<Window> {
102 ctx(|s| s.get_window())
103}
104
105pub fn get_device() -> Arc<Device> {
113 ctx(|s| s.device.clone())
114}
115
116pub fn get_queue() -> Queue {
124 ctx(|s| s.queue.clone())
125}
126
127pub fn add_post_render_hook(
136 hook: impl FnMut(&Device, &Queue, &mut CommandEncoder, &TextureView, (u32, u32)) + 'static,
137) {
138 ctx(|s| s.post_render_hooks.push(Box::new(hook)));
139}
140
141pub fn get_surface_config() -> Arc<Mutex<SurfaceConfiguration>> {
149 ctx(|s| s.config.clone())
150}
151
152pub fn get_window_events() -> Vec<WindowEvent> {
160 ctx(|s| s.event_list.clone())
161}
162
163pub fn set_window_passthrough(passthrough: bool) {
165 if STATE.get().is_some() {
166 return ctx(|s| s.set_window_passthrough(passthrough));
167 }
168
169 PENDING_CONFIG.with_borrow_mut(|s| s.window_passthrough = Some(passthrough));
170}
171
172pub fn set_window_level(level: WindowLevel) {
174 if STATE.get().is_some() {
175 return ctx(|s| s.set_window_level(level));
176 }
177
178 PENDING_CONFIG.with_borrow_mut(|s| s.window_level = Some(level));
179}
180
181pub fn set_window_enabled_buttons(window_buttons: WindowButtons) {
184 ctx(|s| s.get_window().set_enabled_buttons(window_buttons));
185}
186
187pub fn set_skip_taskbar(skip: bool) {
189 if STATE.get().is_some() {
190 #[cfg(target_os = "windows")]
191 return ctx(|s| s.window.set_skip_taskbar(skip));
192 }
193
194 PENDING_CONFIG.with_borrow_mut(|s| s.skip_taskbar = Some(skip));
195}
196
197pub fn set_window_transparent(transparent: bool) {
200 if STATE.get().is_some() {
201 return get_window().set_transparent(transparent);
202 }
203
204 PENDING_CONFIG.with_borrow_mut(|s| s.window_transparent = Some(transparent));
205}
206
207pub fn set_window_decorations(enabled: bool) {
209 if STATE.get().is_some() {
210 return get_window().set_decorations(enabled);
211 }
212
213 PENDING_CONFIG.with_borrow_mut(|s| s.window_decorations = Some(enabled));
214}
215
216pub fn set_window_title(title: &str) {
226 if STATE.get().is_some() {
227 return ctx(|s| s.set_window_title(title));
228 }
229
230 PENDING_CONFIG.with_borrow_mut(|s| s.window_title = Some(title.into()));
231}
232
233pub fn set_window_visible(visible: bool) {
242 if STATE.get().is_some() {
243 return ctx(|s| s.set_window_visible(visible));
244 }
245
246 PENDING_CONFIG.with_borrow_mut(|s| s.window_visible = Some(visible));
247}
248
249pub fn set_window_icon(path: &str) {
257 let img = image::open(path)
258 .expect("image icon does not exist at path")
259 .into_rgba8();
260 let (width, height) = img.dimensions();
261 let rgba = img.into_raw();
262
263 if STATE.get().is_some() {
264 return ctx(|s| s.set_window_icon(rgba, width, height));
265 }
266
267 PENDING_CONFIG.with_borrow_mut(|s| s.window_icon = Some((rgba, width, height)));
268}
269
270pub fn set_window_icon_bytes(bytes: &[u8]) {
272 let img = image::load_from_memory(bytes)
273 .expect("image icon does not exist at path")
274 .into_rgba8();
275 let (width, height) = img.dimensions();
276 let rgba = img.into_raw();
277
278 if STATE.get().is_some() {
279 return ctx(|s| s.set_window_icon(rgba, width, height));
280 }
281
282 PENDING_CONFIG.with_borrow_mut(|s| s.window_icon = Some((rgba, width, height)));
283}
284
285pub fn set_window_x(x: i32) {
293 if STATE.get().is_some() {
294 return ctx(|s| s.set_window_x(x));
295 }
296
297 PENDING_CONFIG.with_borrow_mut(|s| s.window_x = Some(x));
298}
299
300pub fn set_window_y(y: i32) {
308 if STATE.get().is_some() {
309 return ctx(|s| s.set_window_y(y));
310 }
311
312 PENDING_CONFIG.with_borrow_mut(|s| s.window_y = Some(y));
313}
314
315pub fn set_window_position(x: i32, y: i32) {
323 set_window_x(x);
324 set_window_y(y);
325}
326
327pub fn window_width() -> f32 {
329 ctx(|s| s.window_width())
330}
331
332pub fn window_height() -> f32 {
334 ctx(|s| s.window_height())
335}
336
337pub fn window_size() -> Vector2 {
339 ctx(|s| Vector2::new(s.window_width(), s.window_height()))
340}
341
342pub fn window_position() -> (f32, f32) {
344 ctx(|s| s.window_position())
345}
346
347pub fn window_position_vec2() -> Vector2 {
349 ctx(|s| s.window_position().into())
350}
351
352pub fn window_x() -> f32 {
354 ctx(|s| s.window_x())
355}
356
357pub fn window_y() -> f32 {
359 ctx(|s| s.window_y())
360}
361
362pub fn set_window_width(w: u32) {
370 if STATE.get().is_some() {
371 return ctx(|s| s.set_window_w(w));
372 }
373
374 PENDING_CONFIG.with_borrow_mut(|s| s.window_width = Some(w));
375}
376
377pub fn set_window_height(h: u32) {
385 if STATE.get().is_some() {
386 return ctx(|s| s.set_window_h(h));
387 }
388
389 PENDING_CONFIG.with_borrow_mut(|s| s.window_height = Some(h));
390}
391
392pub fn set_window_size(w: u32, h: u32) {
400 if STATE.get().is_some() {
401 return ctx(|s| s.set_window_size(w, h));
402 }
403
404 PENDING_CONFIG.with_borrow_mut(|s| {
405 s.window_width = Some(w);
406 s.window_height = Some(h);
407 });
408}
409
410pub fn set_window_resizable(resizeable: bool) {
412 ctx(|s| s.window.set_resizable(resizeable));
413}
414
415pub fn get_fps() -> f32 {
426 ctx(|s| s.get_fps())
427}
428
429pub fn set_target_fps(fps: usize) {
437 if STATE.get().is_some() {
438 return ctx(|s| s.set_target_fps(fps));
439 }
440
441 PENDING_CONFIG.with_borrow_mut(|s| s.target_fps = Some(fps));
442}
443
444pub fn set_fps_capped(capped: bool) {
453 if STATE.get().is_some() {
454 return ctx(|s| s.set_fps_capped(capped));
455 }
456
457 PENDING_CONFIG.with_borrow_mut(|s| s.fps_capped = Some(capped));
458}
459
460pub fn get_frame_time() -> f32 {
469 ctx(|s| s.get_frame_time())
470}
471
472pub fn get_frames() -> usize {
481 ctx(|s| s.get_frames())
482}
483
484pub fn mouse_position() -> (f32, f32) {
494 ctx(|s| s.mouse_state.get_position().into())
495}
496
497pub fn mouse_position_vec2() -> Vector2 {
506 ctx(|s| s.mouse_state.get_position())
507}
508
509pub fn mouse_screen_position_vec2() -> Vector2 {
511 ctx(|s| s.mouse_state.get_screen_position())
512}
513
514pub fn mouse_screen_position() -> (f32, f32) {
516 ctx(|s| s.mouse_state.get_screen_position().into())
517}
518
519pub fn mouse_wheel() -> Vector2 {
528 ctx(|s| s.mouse_state.get_mouse_wheel())
529}
530
531pub fn set_mouse_icon(cursor_icon: CursorIcon) {
539 ctx(|s| s.window.set_cursor(cursor_icon))
540}
541pub fn focus_window() {
543 get_window().focus_window();
544}
545
546pub fn is_mouse_button_down(btn: MouseButton) -> bool {
557 ctx(|s| s.mouse_state.is_button_down(btn))
558}
559
560pub fn is_mouse_button_pressed(btn: MouseButton) -> bool {
570 ctx(|s| s.mouse_state.is_button_pressed(btn))
571}
572
573pub fn is_mouse_button_released(btn: MouseButton) -> bool {
584 ctx(|s| s.mouse_state.is_button_released(btn))
585}
586
587pub fn is_key_down(key: KeyCode) -> bool {
596 ctx(|s| s.keyboard_state.is_key_down(key))
597}
598
599pub fn is_key_pressed(key: KeyCode) -> bool {
609 ctx(|s| s.keyboard_state.is_key_pressed(key))
610}
611
612pub fn is_key_released(key: KeyCode) -> bool {
622 ctx(|s| s.keyboard_state.is_key_released(key))
623}
624
625pub fn get_axis(left: KeyCode, right: KeyCode) -> f32 {
627 ctx(|s| match (is_key_down(left), is_key_down(right)) {
628 (true, false) => -1.0,
629 (false, true) => 1.0,
630 _ => 0.0,
631 })
632}
633
634pub fn get_vector(left: KeyCode, right: KeyCode, up: KeyCode, down: KeyCode) -> Vector2 {
637 ctx(|s| {
638 Vector2::new(
639 match (is_key_down(left), is_key_down(right)) {
640 (true, false) => -1.0,
641 (false, true) => 1.0,
642 _ => 0.0,
643 },
644 match (is_key_down(up), is_key_down(down)) {
645 (true, false) => -1.0,
646 (false, true) => 1.0,
647 _ => 0.0,
648 },
649 )
650 })
651}
652
653pub fn mouse_position_global() -> (f32, f32) {
657 ctx(|s| s.mouse_state.get_position_global().into())
658}
659
660pub fn mouse_position_vec2_global() -> Vector2 {
661 ctx(|s| s.mouse_state.get_position_global())
662}
663
664pub fn mouse_screen_position_global() -> (f32, f32) {
666 ctx(|s| s.mouse_state.get_screen_position_global().into())
667}
668
669pub fn mouse_screen_position_vec2_global() -> Vector2 {
670 ctx(|s| s.mouse_state.get_screen_position_global())
671}
672
673pub fn mouse_wheel_global() -> Vector2 {
675 ctx(|s| s.mouse_state.get_mouse_wheel_global())
676}
677
678pub fn is_mouse_button_down_global(btn: MouseButton) -> bool {
679 ctx(|s| s.mouse_state.is_button_down_global(btn))
680}
681
682pub fn is_mouse_button_pressed_global(btn: MouseButton) -> bool {
683 ctx(|s| s.mouse_state.is_button_pressed_global(btn))
684}
685
686pub fn is_mouse_button_released_global(btn: MouseButton) -> bool {
687 ctx(|s| s.mouse_state.is_button_released_global(btn))
688}
689
690pub fn is_key_down_global(key: KeyCode) -> bool {
691 ctx(|s| s.keyboard_state.is_key_down_global(key))
692}
693
694pub fn is_key_pressed_global(key: KeyCode) -> bool {
695 ctx(|s| s.keyboard_state.is_key_pressed_global(key))
696}
697
698pub fn is_key_released_global(key: KeyCode) -> bool {
699 ctx(|s| s.keyboard_state.is_key_released_global(key))
700}
701
702pub fn get_axis_global(left: KeyCode, right: KeyCode) -> f32 {
704 ctx(|s| {
705 match (
706 s.keyboard_state.is_key_down_global(left),
707 s.keyboard_state.is_key_down_global(right),
708 ) {
709 (true, false) => -1.0,
710 (false, true) => 1.0,
711 _ => 0.0,
712 }
713 })
714}
715
716pub fn get_vector_global(left: KeyCode, right: KeyCode, up: KeyCode, down: KeyCode) -> Vector2 {
718 Vector2::new(
719 get_axis_global(left, right),
720 get_axis_global(up, down),
721 )
722}
723
724pub fn block_key(key: KeyCode) { ctx(|s| s.block_key(key)) }
727
728pub fn unblock_key(key: KeyCode) { ctx(|s| s.unblock_key(key)) }
730
731pub fn clear_background(color: Color) {
742 if STATE.get().is_some() {
743 return ctx(|s| {
744 s.clear_color = Some(color);
745 s.draw_state.clear();
746 });
747 }
748
749 PENDING_CONFIG.with_borrow_mut(|c| c.window_clear_color = Some(color));
750}
751
752pub fn draw_rectangle(x: f32, y: f32, w: f32, h: f32, color: Color) {
761 draw_rectangle_rounded(x, y, w, h, 0.0, color);
762}
763
764pub fn draw_rectangle_rounded(x: f32, y: f32, w: f32, h: f32, radius: f32, color: Color) {
773 draw_rectangle_rounded_ex(x, y, w, h, radius, radius, radius, radius, color)
774}
775
776pub fn draw_rectangle_rounded_ex(
791 x: f32,
792 y: f32,
793 w: f32,
794 h: f32,
795 top_left: f32,
796 top_right: f32,
797 bottom_left: f32,
798 bottom_right: f32,
799 color: Color,
800) {
801 ctx(|s| {
802 s.draw_state.draw_rectangle(
803 x,
804 y,
805 w,
806 h,
807 top_left,
808 top_right,
809 bottom_left,
810 bottom_right,
811 color,
812 )
813 });
814}
815
816pub fn draw_rectangle_from_rect(rect: Rect, color: Color) {
824 draw_rectangle(rect.x, rect.y, rect.w, rect.h, color);
825}
826
827pub fn draw_rectangle_rounded_from_rect(rect: Rect, radius: f32, color: Color) {
836 draw_rectangle_rounded(rect.x, rect.y, rect.w, rect.h, radius, color);
837}
838
839pub fn draw_rectangle_lines_rounded_from_rect(
848 rect: Rect,
849 radius: f32,
850 thickness: f32,
851 color: Color,
852) {
853 draw_rectangle_lines_rounded(rect.x, rect.y, rect.w, rect.h, radius, thickness, color);
854}
855
856pub fn draw_rectangle_lines_rounded_from_rect_ex(
865 rect: Rect,
866 top_left: f32,
867 top_right: f32,
868 bottom_left: f32,
869 bottom_right: f32,
870 thickness: f32,
871 color: Color,
872) {
873 draw_rectangle_lines_rounded_ex(
874 rect.x,
875 rect.y,
876 rect.w,
877 rect.h,
878 top_left,
879 top_right,
880 bottom_left,
881 bottom_right,
882 thickness,
883 color,
884 );
885}
886
887pub fn draw_rectangle_rounded_from_rect_ex(
901 rect: Rect,
902 top_left: f32,
903 top_right: f32,
904 bottom_left: f32,
905 bottom_right: f32,
906 color: Color,
907) {
908 draw_rectangle_rounded_ex(
909 rect.x,
910 rect.y,
911 rect.w,
912 rect.h,
913 top_left,
914 top_right,
915 bottom_left,
916 bottom_right,
917 color,
918 );
919}
920
921pub fn draw_rectangle_lines(x: f32, y: f32, w: f32, h: f32, thickness: f32, color: Color) {
929 draw_rectangle_lines_rounded(x, y, w, h, 0.0, thickness, color)
930}
931
932pub fn draw_rectangle_lines_from_rect(rect: Rect, thickness: f32, color: Color) {
940 draw_rectangle_lines(rect.x, rect.y, rect.w, rect.h, thickness, color);
941}
942
943pub fn draw_rectangle_lines_rounded(
954 x: f32,
955 y: f32,
956 w: f32,
957 h: f32,
958 radius: f32,
959 thickness: f32,
960 color: Color,
961) {
962 draw_rectangle_lines_rounded_ex(x, y, w, h, radius, radius, radius, radius, thickness, color);
963}
964
965pub fn draw_rectangle_lines_rounded_ex(
980 x: f32,
981 y: f32,
982 w: f32,
983 h: f32,
984 top_left: f32,
985 top_right: f32,
986 bottom_left: f32,
987 bottom_right: f32,
988 thickness: f32,
989 color: Color,
990) {
991 ctx(|s| {
992 s.draw_state.draw_rectangle_lines(
993 x,
994 y,
995 w,
996 h,
997 top_left,
998 top_right,
999 bottom_left,
1000 bottom_right,
1001 thickness,
1002 color,
1003 )
1004 });
1005}
1006
1007pub fn draw_rectangle_rotated(x: f32, y: f32, w: f32, h: f32, rotation: f32, color: Color) {
1016 ctx(|s| {
1017 s.draw_state
1018 .draw_rectangle_rotated(x, y, w, h, rotation, 0.0, 0.0, 0.0, 0.0, color)
1019 });
1020}
1021
1022pub fn draw_rectangle_lines_rotated(
1025 x: f32,
1026 y: f32,
1027 w: f32,
1028 h: f32,
1029 rotation: f32,
1030 thickness: f32,
1031 color: Color,
1032) {
1033 ctx(|s| {
1034 s.draw_state.draw_rectangle_lines_rotated(
1035 x, y, w, h, rotation, 0.0, 0.0, 0.0, 0.0, thickness, color,
1036 )
1037 });
1038}
1039
1040pub fn draw_rectangle_rounded_rotated(
1044 x: f32,
1045 y: f32,
1046 w: f32,
1047 h: f32,
1048 rotation: f32,
1049 radius: f32,
1050 color: Color,
1051) {
1052 draw_rectangle_rounded_rotated_ex(x, y, w, h, rotation, radius, radius, radius, radius, color);
1053}
1054
1055pub fn draw_rectangle_rounded_rotated_ex(
1056 x: f32,
1057 y: f32,
1058 w: f32,
1059 h: f32,
1060 rotation: f32,
1061 top_left: f32,
1062 top_right: f32,
1063 bottom_left: f32,
1064 bottom_right: f32,
1065 color: Color,
1066) {
1067 ctx(|s| {
1068 s.draw_state.draw_rectangle_rotated(
1069 x,
1070 y,
1071 w,
1072 h,
1073 rotation,
1074 top_left,
1075 top_right,
1076 bottom_left,
1077 bottom_right,
1078 color,
1079 )
1080 });
1081}
1082
1083pub fn draw_rectangle_lines_rounded_rotated(
1087 x: f32,
1088 y: f32,
1089 w: f32,
1090 h: f32,
1091 rotation: f32,
1092 radius: f32,
1093 thickness: f32,
1094 color: Color,
1095) {
1096 draw_rectangle_lines_rounded_rotated_ex(
1097 x, y, w, h, rotation, radius, radius, radius, radius, thickness, color,
1098 );
1099}
1100
1101pub fn draw_rectangle_lines_rounded_rotated_ex(
1105 x: f32,
1106 y: f32,
1107 w: f32,
1108 h: f32,
1109 rotation: f32,
1110 top_left: f32,
1111 top_right: f32,
1112 bottom_left: f32,
1113 bottom_right: f32,
1114 thickness: f32,
1115 color: Color,
1116) {
1117 ctx(|s| {
1118 s.draw_state.draw_rectangle_lines_rotated(
1119 x,
1120 y,
1121 w,
1122 h,
1123 rotation,
1124 top_left,
1125 top_right,
1126 bottom_left,
1127 bottom_right,
1128 thickness,
1129 color,
1130 )
1131 });
1132}
1133
1134pub fn draw_circle(x: f32, y: f32, r: f32, color: Color) {
1142 ctx(|s| s.draw_state.draw_circle(x, y, r, color));
1143}
1144
1145pub fn draw_circle_lines(x: f32, y: f32, r: f32, thickness: f32, color: Color) {
1154 ctx(|s| s.draw_state.draw_circle_lines(x, y, r, thickness, color));
1155}
1156
1157pub fn draw_triangle(x1: f32, y1: f32, x2: f32, y2: f32, x3: f32, y3: f32, color: Color) {
1166 ctx(|s| s.draw_state.draw_triangle(x1, y1, x2, y2, x3, y3, color));
1167}
1168
1169pub fn draw_triangle_lines(
1178 x1: f32,
1179 y1: f32,
1180 x2: f32,
1181 y2: f32,
1182 x3: f32,
1183 y3: f32,
1184 thickness: f32,
1185 color: Color,
1186) {
1187 ctx(|s| {
1188 s.draw_state
1189 .draw_triangle_lines(x1, y1, x2, y2, x3, y3, thickness, color)
1190 });
1191}
1192
1193pub fn draw_line(x1: f32, y1: f32, x2: f32, y2: f32, thickness: f32, color: Color) {
1202 ctx(|s| s.draw_state.draw_line(x1, y1, x2, y2, thickness, color))
1203}
1204
1205pub fn draw_poly_line(points: &[Vector2], thickness: f32, color: Color, closed: bool) {
1216 ctx(|s| {
1217 s.draw_state
1218 .draw_poly_line_miter(points, thickness, color, closed)
1219 })
1220}
1221
1222pub fn draw_poly_line_rounded(points: &[Vector2], thickness: f32, color: Color, closed: bool) {
1233 ctx(|s| {
1234 s.draw_state
1235 .draw_poly_line(points, thickness, color, closed, true)
1236 })
1237}
1238
1239pub fn draw_polygon(points: &[Vector2], color: Color) {
1252 ctx(|s| s.draw_state.draw_polygon(points, color))
1253}
1254
1255pub fn draw_polygon_concave(points: &[Vector2], color: Color) {
1269 ctx(|s| s.draw_state.draw_polygon_concave(points, color))
1270}
1271
1272pub fn draw_text(t: &str, x: f32, y: f32, size: f32, font: Option<&Font>, color: Color) {
1281 ctx(|s| s.draw_state.draw_text(&s.fonts, t, x, y, size, font, color));
1282}
1283
1284pub fn draw_rich_text<'a, I>(
1303 position: Vector2,
1304 size: f32,
1305 font: Option<&Font>,
1306 color: Color,
1307 spans: I,
1308) where
1309 I: IntoIterator,
1310 I::Item: Borrow<Span<'a>>,
1311{
1312 ctx(|s| {
1313 s.draw_state
1314 .draw_richtext(position, size, font, color, spans)
1315 })
1316}
1317
1318pub fn load_font_from_path(path: &str) -> Font {
1332 if STATE.get().is_some() {
1333 return ctx(|s| {
1334 s.load_font_from_path(path);
1335 s.fonts[s.fonts.len() - 1].clone()
1336 });
1337 }
1338
1339 PENDING_CONFIG.with_borrow_mut(|s| {
1340 let font = Font::from_path(s.fonts.len() + 1, path);
1341 s.fonts.push(font.clone());
1342 font
1343 })
1344}
1345
1346pub fn load_font_from_bytes(bytes: &[u8]) -> Font {
1360 if STATE.get().is_some() {
1361 return ctx(|s| {
1362 s.load_font_from_bytes(bytes);
1363 s.fonts[s.fonts.len() - 1].clone()
1364 });
1365 }
1366
1367 PENDING_CONFIG.with_borrow_mut(|s| {
1368 let font = Font::from_bytes(s.fonts.len() + 1, bytes);
1369 s.fonts.push(font.clone());
1370 font
1371 })
1372}
1373
1374pub fn measure_text(t: &str, size: f32, font: Option<&Font>) -> Vector2 {
1376 let (w, h) = ctx(|s| s.measure_text(t, size, font));
1377 Vector2::new(w, h)
1378}
1379
1380pub fn draw_arrow(
1383 x1: f32,
1384 y1: f32,
1385 x2: f32,
1386 y2: f32,
1387 thickness: f32,
1388 head_size: f32,
1389 color: Color,
1390) {
1391 ctx(|s| {
1392 s.draw_state
1393 .draw_arrow(x1, y1, x2, y2, thickness, head_size, color)
1394 });
1395}
1396
1397pub fn screen_size() -> Vector2 {
1399 let win = get_window();
1400 match win.current_monitor() {
1401 Some(m) => {
1402 let s = m.size();
1403 Vector2::new(s.width as f32, s.height as f32)
1404 }
1405 None => window_size(),
1406 }
1407}
1408
1409pub fn screen_width() -> f32 {
1410 screen_size().x
1411}
1412pub fn screen_height() -> f32 {
1413 screen_size().y
1414}
1415
1416pub fn create_empty_texture(width: u32, height: u32, filter_type: FilterType) -> Texture {
1420 ctx(|s| {
1421 let gpu = GpuTexture::empty(
1422 &s.device,
1423 width,
1424 height,
1425 filter_type,
1426 wgpu::TextureFormat::Rgba8UnormSrgb,
1427 )
1428 .expect("Couldn't create empty GpuTexture");
1429
1430 Texture {
1431 id: s.add_gpu_texture(gpu, false),
1432 width,
1433 height,
1434 }
1435 })
1436}
1437
1438pub fn load_texture(path: &str) -> Texture {
1440 ctx(|s| {
1441 let image = image::load_from_memory(&std::fs::read(path).unwrap()).unwrap();
1442 let width = image.width();
1443 let height = image.height();
1444
1445 Texture {
1446 id: s.add_texture(image, FilterType::Linear),
1447 width,
1448 height,
1449 }
1450 })
1451}
1452
1453pub fn load_texture_with_filter_type(path: &str, filter_type: FilterType) -> Texture {
1455 ctx(|s| {
1456 let image = image::load_from_memory(&std::fs::read(path).unwrap()).unwrap();
1457 let width = image.width();
1458 let height = image.height();
1459
1460 Texture {
1461 id: s.add_texture(image, filter_type),
1462 width,
1463 height,
1464 }
1465 })
1466}
1467
1468pub fn load_texture_from_bytes(bytes: &[u8]) -> Texture {
1470 ctx(|s| {
1471 let image = image::load_from_memory(bytes).unwrap();
1472 let (width, height) = image.dimensions();
1473
1474 Texture {
1475 id: s.add_texture(image, FilterType::Linear),
1476 width,
1477 height,
1478 }
1479 })
1480}
1481
1482pub fn load_texture_from_bytes_with_filter_type(bytes: &[u8], filter_type: FilterType) -> Texture {
1484 ctx(|s| {
1485 let image = image::load_from_memory(bytes).unwrap();
1486 let (width, height) = image.dimensions();
1487
1488 Texture {
1489 id: s.add_texture(image, filter_type),
1490 width,
1491 height,
1492 }
1493 })
1494}
1495
1496pub fn load_texture_from_data(width: u32, height: u32, data: &[f32]) -> Texture {
1498 ctx(|s| {
1499 let img_buf = ImageBuffer::<Rgba<f32>, Vec<f32>>::from_raw(width, height, data.to_vec())
1500 .expect("Buffer size mismatch");
1501
1502 let dynamic_img = DynamicImage::ImageRgba32F(img_buf);
1503
1504 Texture {
1505 id: s.add_texture(dynamic_img, FilterType::Linear),
1506 width,
1507 height,
1508 }
1509 })
1510}
1511
1512pub fn load_texture_from_data_with_filter_type(
1516 width: u32,
1517 height: u32,
1518 data: &[f32],
1519 filter_type: FilterType,
1520) -> Texture {
1521 ctx(|s| {
1522 let img_buf = ImageBuffer::<Rgba<f32>, Vec<f32>>::from_raw(width, height, data.to_vec())
1523 .expect("Buffer size mismatch");
1524
1525 let dynamic_img = DynamicImage::ImageRgba32F(img_buf);
1526
1527 Texture {
1528 id: s.add_texture(dynamic_img, filter_type),
1529 width,
1530 height,
1531 }
1532 })
1533}
1534
1535pub fn load_texture_from_image(image: &Image) -> Texture {
1537 let tex = create_empty_texture(image.width, image.height, image.filter_type);
1538 update_texture(tex, image);
1539
1540 tex
1541}
1542
1543pub fn draw_texture(texture: Texture, x: f32, y: f32, w: f32, h: f32, tint: Color) {
1546 ctx(|s| s.draw_state.draw_texture(texture, x, y, w, h, tint))
1547}
1548
1549pub fn draw_texture_ex(texture: Texture, x: f32, y: f32, p: DrawTextureParams) {
1552 ctx(|s| s.draw_state.draw_texture_ex(texture, x, y, p))
1553}
1554
1555pub fn update_texture(texture: Texture, image: &Image) {
1557 ctx(|s| s.update_texture(texture.id, image))
1558}
1559
1560pub fn render_target(width: u32, height: u32, filter_type: FilterType) -> RenderTarget {
1562 ctx(|s| s.create_render_target(width, height, filter_type))
1563}
1564
1565pub fn set_camera(cam: &Camera2D) {
1567 ctx(|s| s.set_camera(cam))
1568}
1569
1570pub fn set_default_camera() {
1572 ctx(|s| s.set_default_camera())
1573}