Skip to main content

dear_imgui_rs/context/
fonts.rs

1use crate::fonts::{Font, FontAtlas, FontAtlasRef, SharedFontAtlas};
2use crate::sys;
3
4use super::Context;
5use super::binding::{CTX_MUTEX, with_bound_context};
6
7impl Context {
8    /// Push a font onto the font stack
9    pub fn push_font(&mut self, font: &Font) {
10        let _guard = CTX_MUTEX.lock();
11        unsafe {
12            with_bound_context(self.raw, || {
13                let font_ptr =
14                    crate::fonts::validate_font_for_current_context(font, "Context::push_font()");
15                sys::igPushFont(font_ptr, 0.0);
16            });
17        }
18    }
19
20    /// Pop a font from the font stack
21    ///
22    /// This restores the previous font. Must be paired with a call to `push_font()`.
23    #[doc(alias = "PopFont")]
24    pub fn pop_font(&mut self) {
25        let _guard = CTX_MUTEX.lock();
26        unsafe {
27            with_bound_context(self.raw, || {
28                sys::igPopFont();
29            });
30        }
31    }
32
33    /// Get the current font
34    #[doc(alias = "GetFont")]
35    pub fn current_font(&self) -> &Font {
36        let _guard = CTX_MUTEX.lock();
37        unsafe { with_bound_context(self.raw, || Font::from_raw(sys::igGetFont() as *const _)) }
38    }
39
40    /// Get the current font size
41    #[doc(alias = "GetFontSize")]
42    pub fn current_font_size(&self) -> f32 {
43        let _guard = CTX_MUTEX.lock();
44        unsafe { with_bound_context(self.raw, || sys::igGetFontSize()) }
45    }
46
47    /// Get a read-only view of the font atlas from the IO structure.
48    ///
49    /// Use [`Context::font_atlas_mut`] or [`Context::fonts`] for loading fonts
50    /// or mutating atlas state.
51    pub fn font_atlas(&self) -> FontAtlasRef<'_> {
52        let _guard = CTX_MUTEX.lock();
53
54        // wasm32 import-style builds keep Dear ImGui state in a separate module
55        // and share linear memory. When the experimental font-atlas feature is
56        // enabled, we allow direct access to the atlas pointer, assuming the
57        // provider has been correctly configured via xtask.
58        #[cfg(all(target_arch = "wasm32", feature = "wasm-font-atlas-experimental"))]
59        unsafe {
60            let io = self.io_ptr("Context::font_atlas()");
61            let atlas_ptr = (*io).Fonts;
62            assert!(
63                !atlas_ptr.is_null(),
64                "ImGui IO Fonts pointer is null on wasm; provider not initialized?"
65            );
66            FontAtlasRef::from_raw(atlas_ptr)
67        }
68
69        // Default wasm path: keep this API disabled to avoid accidental UB.
70        #[cfg(all(target_arch = "wasm32", not(feature = "wasm-font-atlas-experimental")))]
71        {
72            panic!(
73                "font_atlas() is not supported on wasm32 targets without \
74                 `wasm-font-atlas-experimental` feature; \
75                 see docs/WASM.md for current limitations."
76            );
77        }
78
79        #[cfg(not(target_arch = "wasm32"))]
80        unsafe {
81            let io = self.io_ptr("Context::font_atlas()");
82            let atlas_ptr = (*io).Fonts;
83            FontAtlasRef::from_raw(atlas_ptr)
84        }
85    }
86
87    /// Get a mutable reference to the font atlas from the IO structure
88    pub fn font_atlas_mut(&mut self) -> FontAtlas {
89        let _guard = CTX_MUTEX.lock();
90
91        // wasm32 import-style builds keep Dear ImGui state in a separate module
92        // and share linear memory. When the experimental font-atlas feature is
93        // enabled, we allow direct access to the atlas pointer, assuming the
94        // provider has been correctly configured via xtask.
95        #[cfg(all(target_arch = "wasm32", feature = "wasm-font-atlas-experimental"))]
96        unsafe {
97            let io = self.io_ptr("Context::font_atlas_mut()");
98            let atlas_ptr = (*io).Fonts;
99            assert!(
100                !atlas_ptr.is_null(),
101                "ImGui IO Fonts pointer is null on wasm; provider not initialized?"
102            );
103            return FontAtlas::from_raw(atlas_ptr);
104        }
105
106        // Default wasm path: keep this API disabled to avoid accidental UB.
107        #[cfg(all(target_arch = "wasm32", not(feature = "wasm-font-atlas-experimental")))]
108        {
109            panic!(
110                "font_atlas_mut()/fonts() are not supported on wasm32 targets yet; \
111                 enable `wasm-font-atlas-experimental` to opt-in for experiments."
112            );
113        }
114
115        #[cfg(not(target_arch = "wasm32"))]
116        unsafe {
117            let io = self.io_ptr("Context::font_atlas_mut()");
118            let atlas_ptr = (*io).Fonts;
119            FontAtlas::from_raw(atlas_ptr)
120        }
121    }
122
123    /// Returns the font atlas (alias for font_atlas_mut)
124    ///
125    /// This provides compatibility with imgui-rs naming convention
126    pub fn fonts(&mut self) -> FontAtlas {
127        self.font_atlas_mut()
128    }
129
130    /// Attempts to clone the interior shared font atlas **if it exists**.
131    pub fn clone_shared_font_atlas(&mut self) -> Option<SharedFontAtlas> {
132        self.shared_font_atlas.clone()
133    }
134}