use cosmic_text::SubpixelBin;
use std::sync::OnceLock;
const CRISP_BELOW: f32 = 2.0;
const GAMMA: f32 = 1.45;
pub(crate) fn is_crisp(scale: f32) -> bool {
scale < CRISP_BELOW
}
pub(crate) fn snap_x(bin: &mut SubpixelBin) -> i32 {
let carry = i32::from(matches!(bin, SubpixelBin::Two | SubpixelBin::Three));
*bin = SubpixelBin::Zero;
carry
}
pub(crate) fn boost(mask: &mut [u8]) {
static LUT: OnceLock<[u8; 256]> = OnceLock::new();
let lut = LUT.get_or_init(|| {
std::array::from_fn(|i| ((i as f32 / 255.0).powf(1.0 / GAMMA) * 255.0).round().clamp(0.0, 255.0) as u8)
});
for value in mask {
*value = lut[*value as usize];
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn solo_las_pantallas_de_densidad_normal_se_ajustan() {
assert!(is_crisp(1.0) && is_crisp(1.5));
assert!(!is_crisp(2.0) && !is_crisp(3.0));
}
#[test]
fn la_posicion_se_redondea_al_pixel_mas_cercano() {
let casos = [(SubpixelBin::Zero, 0), (SubpixelBin::One, 0), (SubpixelBin::Two, 1), (SubpixelBin::Three, 1)];
for (mut bin, carry) in casos {
assert_eq!(snap_x(&mut bin), carry);
assert_eq!(bin, SubpixelBin::Zero);
}
}
#[test]
fn el_refuerzo_conserva_los_extremos_y_sube_los_medios_tonos() {
let mut mask = [0u8, 64, 128, 255];
boost(&mut mask);
assert_eq!((mask[0], mask[3]), (0, 255));
assert!(mask[1] > 64 && mask[2] > 128);
assert!(mask.windows(2).all(|pair| pair[0] < pair[1]), "sigue siendo monótona");
}
}