use std::sync::{LazyLock, RwLock};
use gtk::{
ffi::GTK_STYLE_PROVIDER_PRIORITY_APPLICATION,
gdk,
pango::{self, FontDescription},
prelude::WidgetExt,
};
use tracing::{debug, info, warn};
pub static FONT_CONTEXT: LazyLock<FontContext> = LazyLock::new(FontContext::default);
#[derive(Default, Debug)]
pub struct FontContext {
font_description: RwLock<FontDescription>,
}
impl FontContext {
pub fn set_font_description(&self, font_description: FontDescription) {
let mut font_description_w = self.font_description.write().expect("supposed to write");
*font_description_w = font_description;
}
pub fn font_description(&self) -> FontDescription {
let font_description = self.font_description.read().expect("supposed to read");
font_description.clone()
}
}
pub fn is_default_font(family: &str, size: u32) -> bool {
family.is_empty() && size == 0
}
pub fn create_provider(font_description: &Option<&FontDescription>) -> Option<gtk::CssProvider> {
let Some(font_description) = font_description else {
info!("set font default");
return None;
};
let family = font_description.family();
let size = font_description.size() / pango::SCALE;
info!("set font {:?}", font_description.to_string());
debug!(
"set familly {:?} gravity {:?} weight {:?} size {} variations {:?} stretch {:?}",
font_description.family(),
font_description.gravity(),
font_description.weight(),
font_description.size(),
font_description.variations(),
font_description.stretch(),
);
let provider = gtk::CssProvider::new();
let mut css = String::with_capacity(100);
css.push_str("textview {");
css.push_str("font-size: ");
css.push_str(&size.to_string());
css.push_str("px;\n");
if let Some(family) = family {
css.push_str("font-family: ");
css.push('"');
css.push_str(family.as_str());
css.push_str("\";\n");
}
css.push('}');
provider.load_from_string(&css);
Some(provider)
}
pub fn set_text_view_font(
old_provider: Option<>k::CssProvider>,
new_provider: Option<>k::CssProvider>,
text_view: >k::TextView,
) {
set_text_view_font_display(old_provider, new_provider, &text_view.display())
}
pub fn set_text_view_font_display(
old_provider: Option<>k::CssProvider>,
new_provider: Option<>k::CssProvider>,
display: &gdk::Display,
) {
if let Some(old_provider) = old_provider {
info!("rem old font provider");
let provider = gtk::CssProvider::new();
let css = String::from("textview {}");
provider.load_from_string(&css);
gtk::style_context_remove_provider_for_display(display, old_provider);
};
if let Some(new_provider) = new_provider {
info!("add new font provider");
gtk::style_context_add_provider_for_display(
display,
new_provider,
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION as u32,
);
}
}
pub fn set_font_context(text_view: >k::TextView) {
let context = text_view.pango_context();
let font_description = context.font_description();
if let Some(font_description) = font_description {
info!("Font description {font_description}");
FONT_CONTEXT.set_font_description(font_description);
} else {
warn!("NO FONT Description")
}
}