use crate::scene::text::{Face, Measurer};
#[derive(Clone, Copy, Debug, Default)]
pub struct Arial;
const REGULAR: &str = "7q7q9vfgfgopij5b9999atg87q997q7qfgfgfgfgfgfgfgfgfgfg7q7qg8g8g8fgs7ijijk2k2ijgzlmk27qdwijfgn5k2lmijlmk2ijgzk2ijq8ijijgz7q7q7qd1fg99fgfgdwfgfg7qfgfg6666dw66n5fgfgfgfg99dw7qfgdwk2dwdwdw9a789ag8";
const BOLD: &str = "7q99d6fgfgopk26m9999atg87q997q7qfgfgfgfgfgfgfgfgfgfg9999g8g8g8gzr3k2k2k2k2ijgzlmk27qfgk2gzn5k2lmijlmk2ijgzk2ijq8ijijgz997q99g8fg99fggzfggzfg99gzgz7q7qfg7qopgzgzgzgzatfg99gzfglmfgfgdwat7satg8";
fn advance(table: &str, c: u32) -> u32 {
let i = 2 * (c - 32) as usize;
u32::from_str_radix(&table[i..i + 2], 36).unwrap_or(0)
}
fn is_wide(c: u32) -> bool {
matches!(c, 0x1100..=0x115f | 0x2e80..=0xa4cf | 0xac00..=0xd7a3 | 0xf900..=0xfaff
| 0xfe30..=0xfe4f | 0xff00..=0xff60 | 0xffe0..=0xffe6)
}
fn is_zero_width(c: u32) -> bool {
matches!(c, 0xad | 0x300..=0x36f | 0x200b..=0x200f | 0xfe00..=0xfe0f | 0xfeff)
}
impl Measurer for Arial {
fn width(&self, s: &str, size: f64, f: Face) -> f64 {
let mono = f.contains(Face::MONO);
let table = if f.contains(Face::BOLD) {
BOLD
} else {
REGULAR
};
let mut units = 0;
for c in s.chars().map(u32::from) {
units += match c {
0..32 => 0,
32..127 if mono => 600,
32..127 => advance(table, c),
_ if is_zero_width(c) => 0,
_ if c > 0xffff || is_wide(c) => {
if mono {
1200
} else {
1000
}
}
_ if mono => 600,
_ => 580,
};
}
f64::from(units) * size / 1000.0
}
}