use std::cell::RefCell;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use crate::text::Font;
static TYPOGRAPHY_EPOCH: AtomicU64 = AtomicU64::new(1);
pub fn current_typography_epoch() -> u64 {
TYPOGRAPHY_EPOCH.load(Ordering::Relaxed)
}
fn bump_typography_epoch() {
TYPOGRAPHY_EPOCH.fetch_add(1, Ordering::Relaxed);
}
thread_local! {
static SYSTEM_FONT: RefCell<Option<Arc<Font>>> = RefCell::new(None);
static FONT_SIZE_SCALE: RefCell<f64> = RefCell::new(1.0);
static LCD_ENABLED: RefCell<bool> = RefCell::new(false);
static HINTING_ENABLED: RefCell<bool> = RefCell::new(false);
static GAMMA: RefCell<f64> = RefCell::new(1.0);
static WIDTH: RefCell<f64> = RefCell::new(1.0);
static INTERVAL: RefCell<f64> = RefCell::new(0.0);
static FAUX_WEIGHT: RefCell<f64> = RefCell::new(0.0);
static FAUX_ITALIC: RefCell<f64> = RefCell::new(0.0);
static PRIMARY_WEIGHT: RefCell<f64> = RefCell::new(1.0 / 3.0);
}
pub fn current_system_font() -> Option<Arc<Font>> {
SYSTEM_FONT.with(|c| c.borrow().clone())
}
pub fn set_system_font(font: Option<Arc<Font>>) {
SYSTEM_FONT.with(|c| *c.borrow_mut() = font);
bump_typography_epoch();
}
pub fn current_font_size_scale() -> f64 {
FONT_SIZE_SCALE.with(|c| *c.borrow())
}
pub fn set_font_size_scale(scale: f64) {
let clamped = scale.clamp(0.5, 3.0);
FONT_SIZE_SCALE.with(|c| *c.borrow_mut() = clamped);
bump_typography_epoch();
}
pub fn lcd_enabled() -> bool {
LCD_ENABLED.with(|c| *c.borrow())
}
pub fn set_lcd_enabled(on: bool) {
LCD_ENABLED.with(|c| *c.borrow_mut() = on);
bump_typography_epoch();
}
pub fn hinting_enabled() -> bool {
HINTING_ENABLED.with(|c| *c.borrow())
}
pub fn set_hinting_enabled(on: bool) {
HINTING_ENABLED.with(|c| *c.borrow_mut() = on);
bump_typography_epoch();
}
pub fn current_gamma() -> f64 { GAMMA.with(|c| *c.borrow()) }
pub fn set_gamma(v: f64) {
let clamped = v.clamp(0.5, 2.5);
GAMMA.with(|c| *c.borrow_mut() = clamped);
bump_typography_epoch();
}
pub fn current_width() -> f64 { WIDTH.with(|c| *c.borrow()) }
pub fn set_width(v: f64) {
let clamped = v.clamp(0.75, 1.25);
WIDTH.with(|c| *c.borrow_mut() = clamped);
bump_typography_epoch();
}
pub fn current_interval() -> f64 { INTERVAL.with(|c| *c.borrow()) }
pub fn set_interval(v: f64) {
let clamped = v.clamp(-0.2, 0.2);
INTERVAL.with(|c| *c.borrow_mut() = clamped);
bump_typography_epoch();
}
pub fn current_faux_weight() -> f64 { FAUX_WEIGHT.with(|c| *c.borrow()) }
pub fn set_faux_weight(v: f64) {
let clamped = v.clamp(-1.0, 1.0);
FAUX_WEIGHT.with(|c| *c.borrow_mut() = clamped);
bump_typography_epoch();
}
pub fn current_faux_italic() -> f64 { FAUX_ITALIC.with(|c| *c.borrow()) }
pub fn set_faux_italic(v: f64) {
let clamped = v.clamp(-1.0, 1.0);
FAUX_ITALIC.with(|c| *c.borrow_mut() = clamped);
bump_typography_epoch();
}
pub fn current_primary_weight() -> f64 { PRIMARY_WEIGHT.with(|c| *c.borrow()) }
pub fn set_primary_weight(v: f64) {
let clamped = v.clamp(0.0, 1.0);
PRIMARY_WEIGHT.with(|c| *c.borrow_mut() = clamped);
bump_typography_epoch();
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_lcd_flag_default_off() {
set_lcd_enabled(false);
assert!(!lcd_enabled());
set_lcd_enabled(true);
assert!(lcd_enabled());
set_lcd_enabled(false);
}
#[test]
fn test_hinting_flag_default_off() {
set_hinting_enabled(false);
assert!(!hinting_enabled());
set_hinting_enabled(true);
assert!(hinting_enabled());
set_hinting_enabled(false);
}
#[test]
fn test_system_font_default_none() {
set_system_font(None);
assert!(current_system_font().is_none());
}
}