use super::{current_app_context, require_current_app_context, with_render_state};
pub(super) fn normalize_density(density: f32) -> f32 {
if density.is_finite() && density > 0.0 {
density
} else {
1.0
}
}
fn normalize_font_scale(scale: f32) -> f32 {
if scale.is_finite() && scale > 0.0 {
scale.clamp(MIN_FONT_SCALE, MAX_FONT_SCALE)
} else {
1.0
}
}
pub const MIN_FONT_SCALE: f32 = 0.5;
pub const MAX_FONT_SCALE: f32 = 3.0;
pub fn current_density() -> f32 {
with_render_state(|state| f32::from_bits(state.density_bits.get()))
}
pub fn set_density(density: f32) {
let normalized = normalize_density(density);
let new_bits = normalized.to_bits();
with_render_state(|state| {
let old_bits = state.density_bits.replace(new_bits);
if old_bits != new_bits {
state.layout_invalidated.set(true);
}
});
}
pub fn current_font_scale() -> f32 {
current_font_scale_curve().scale()
}
pub fn current_font_scale_curve() -> crate::font_scale::FontScaleCurve {
with_render_state(|state| state.font_scale.get())
}
pub(crate) fn current_host_density() -> Option<(f32, crate::font_scale::FontScaleCurve)> {
current_app_context().map(|context| {
(
f32::from_bits(context.state.density_bits.get()),
context.state.font_scale.get(),
)
})
}
pub(crate) fn text_layout_stamp() -> (u64, u32) {
let context = require_current_app_context("text layout stamp access");
(
context.text.generation(),
context.state.font_scale_fingerprint.get(),
)
}
pub fn scale_sp(sp: f32) -> f32 {
current_font_scale_curve().sp_to_dp(sp)
}
pub fn set_font_scale(scale: f32) {
set_font_scale_curve(crate::font_scale::FontScaleCurve::linear(scale));
}
pub fn set_font_scale_curve(curve: crate::font_scale::FontScaleCurve) {
let normalized = normalize_font_scale(curve.scale());
let curve = if (normalized - curve.scale()).abs() <= f32::EPSILON {
curve
} else {
crate::font_scale::FontScaleCurve::linear(normalized)
};
with_render_state(|state| {
if state.font_scale.get() != curve {
state.font_scale.set(curve);
state.font_scale_identity.set(curve.is_identity());
state.font_scale_fingerprint.set(curve.fingerprint());
state.layout_invalidated.set(true);
}
});
}