use crate::fonts::{Font, FontAtlas, FontAtlasRef, SharedFontAtlas};
use crate::sys;
use std::marker::PhantomData;
use super::Context;
use super::binding::{CTX_MUTEX, with_bound_context};
use super::core::ContextAliveToken;
#[must_use]
pub struct ContextFontStackToken<'ctx> {
ctx: *mut sys::ImGuiContext,
ctx_alive: ContextAliveToken,
_phantom: PhantomData<&'ctx mut Context>,
}
impl<'ctx> ContextFontStackToken<'ctx> {
fn new(ctx: *mut sys::ImGuiContext, ctx_alive: ContextAliveToken) -> Self {
Self {
ctx,
ctx_alive,
_phantom: PhantomData,
}
}
#[doc(alias = "PopFont")]
pub fn pop(self) {}
#[doc(alias = "PopFont")]
pub fn end(self) {}
}
impl Drop for ContextFontStackToken<'_> {
fn drop(&mut self) {
if self.ctx.is_null() || !self.ctx_alive.is_alive() {
return;
}
let _guard = CTX_MUTEX.lock();
unsafe {
with_bound_context(self.ctx, || {
sys::igPopFont();
});
}
}
}
impl Context {
#[doc(alias = "PushFont")]
pub fn push_font(&mut self, font: &Font) -> ContextFontStackToken<'_> {
let _guard = CTX_MUTEX.lock();
unsafe {
with_bound_context(self.raw, || {
let font_ptr =
crate::fonts::validate_font_for_current_context(font, "Context::push_font()");
sys::igPushFont(font_ptr, 0.0);
});
}
ContextFontStackToken::new(self.raw, self.alive_token())
}
#[doc(alias = "GetFont")]
pub fn current_font(&self) -> &Font {
let _guard = CTX_MUTEX.lock();
unsafe { with_bound_context(self.raw, || Font::from_raw(sys::igGetFont() as *const _)) }
}
#[doc(alias = "GetFontSize")]
pub fn current_font_size(&self) -> f32 {
let _guard = CTX_MUTEX.lock();
unsafe { with_bound_context(self.raw, || sys::igGetFontSize()) }
}
pub fn font_atlas(&self) -> FontAtlasRef<'_> {
let _guard = CTX_MUTEX.lock();
#[cfg(all(target_arch = "wasm32", feature = "wasm-font-atlas-experimental"))]
unsafe {
let io = self.io_ptr("Context::font_atlas()");
let atlas_ptr = (*io).Fonts;
assert!(
!atlas_ptr.is_null(),
"ImGui IO Fonts pointer is null on wasm; provider not initialized?"
);
FontAtlasRef::from_raw(atlas_ptr)
}
#[cfg(all(target_arch = "wasm32", not(feature = "wasm-font-atlas-experimental")))]
{
panic!(
"font_atlas() is not supported on wasm32 targets without \
`wasm-font-atlas-experimental` feature; \
see docs/WASM.md for current limitations."
);
}
#[cfg(not(target_arch = "wasm32"))]
unsafe {
let io = self.io_ptr("Context::font_atlas()");
let atlas_ptr = (*io).Fonts;
FontAtlasRef::from_raw(atlas_ptr)
}
}
pub fn font_atlas_mut(&mut self) -> FontAtlas {
let _guard = CTX_MUTEX.lock();
#[cfg(all(target_arch = "wasm32", feature = "wasm-font-atlas-experimental"))]
unsafe {
let io = self.io_ptr("Context::font_atlas_mut()");
let atlas_ptr = (*io).Fonts;
assert!(
!atlas_ptr.is_null(),
"ImGui IO Fonts pointer is null on wasm; provider not initialized?"
);
return FontAtlas::from_raw(atlas_ptr);
}
#[cfg(all(target_arch = "wasm32", not(feature = "wasm-font-atlas-experimental")))]
{
panic!(
"font_atlas_mut()/fonts() are not supported on wasm32 targets yet; \
enable `wasm-font-atlas-experimental` to opt-in for experiments."
);
}
#[cfg(not(target_arch = "wasm32"))]
unsafe {
let io = self.io_ptr("Context::font_atlas_mut()");
let atlas_ptr = (*io).Fonts;
FontAtlas::from_raw(atlas_ptr)
}
}
pub fn fonts(&mut self) -> FontAtlas {
self.font_atlas_mut()
}
pub fn clone_shared_font_atlas(&mut self) -> Option<SharedFontAtlas> {
self.shared_font_atlas.clone()
}
}