pub fn initex_lccode(c: u32) -> i64 {
match c {
0x41..=0x5A => i64::from(c + 32),
0x61..=0x7A => i64::from(c),
_ => 0,
}
}
pub fn initex_uccode(c: u32) -> i64 {
match c {
0x41..=0x5A => i64::from(c),
0x61..=0x7A => i64::from(c - 32),
_ => 0,
}
}
pub fn initex_sfcode(c: u32) -> i64 {
if (0x41..=0x5A).contains(&c) {
999
} else {
1000
}
}
pub const fn math_code(class: u32, fam: u32, chr: u32) -> i64 {
((class as i64) << 21) + ((fam as i64) << 24) + chr as i64
}
pub const fn math_class(code: i64) -> u32 {
((code >> 21) & 7) as u32
}
pub const fn math_fam(code: i64) -> u32 {
((code >> 24) & 0xFF) as u32
}
pub const fn math_char(code: i64) -> u32 {
(code & 0x1F_FFFF) as u32
}
pub const MATH_GIVEN_PACKED: u32 = 1 << 31;
pub const fn math_given_report(g: u32) -> i32 {
if g & MATH_GIVEN_PACKED == 0 {
return g as i32;
}
let code = (g & !MATH_GIVEN_PACKED) as i64;
(math_class(code) * 0x1000 + math_fam(code) * 0x100 + math_char(code)) as i32
}
pub const MATH_ACTIVE: i64 = 1 << 40;
pub const fn math_code_report(code: i64) -> i32 {
if code == MATH_ACTIVE {
8 << 21
} else {
code as i32
}
}
pub fn initex_mathcode(c: u32) -> i64 {
match c {
0x30..=0x39 => math_code(7, 0, c),
0x41..=0x5A | 0x61..=0x7A => math_code(7, 1, c),
_ => i64::from(c),
}
}
pub fn initex_delcode(c: u32) -> i64 {
if c == u32::from(b'.') { 0 } else { -1 }
}
pub fn delcode_from_classic(v: i32) -> i64 {
if v < 0 {
return -1;
}
let v = v as i64;
let small_fam = (v >> 20) & 0xF;
let small_chr = (v >> 12) & 0xFF;
let large_fam = (v >> 8) & 0xF;
let large_chr = v & 0xFF;
(small_fam << 53) | (small_chr << 32) | (large_fam << 21) | large_chr | (1 << 62)
}
pub fn delcode_report(v: i64, _cmd: crate::cmd::Cmd) -> i32 {
if v < 0 {
return -1;
}
if v & (1 << 62) == 0 {
return v as i32;
}
let small_fam = (v >> 53) & 0xF;
let small_chr = (v >> 32) & 0xFF;
let large_fam = (v >> 21) & 0xF;
let large_chr = v & 0xFF;
((small_fam << 20) | (small_chr << 12) | (large_fam << 8) | large_chr) as i32
}
pub fn math_param_is_glue(p: u32) -> bool {
(49..49 + 64).contains(&p)
}
pub const UNDEFINED_MATH_PARAM: i32 = 0x3FFF_FFFF;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn packing_matches_luatex() {
assert_eq!(initex_mathcode('a' as u32), 31457377);
assert_eq!(initex_mathcode('1' as u32), 14680113);
assert_eq!(math_code(1, 2, 0x3B1), 35652529);
assert_eq!(math_code_report(MATH_ACTIVE), 16777216);
}
}