use crate::{FontStyle, FontWeight, FontWidth};
pub trait FromFontconfig: Sized {
fn from_fontconfig(value: i32) -> Self;
}
impl FromFontconfig for FontWeight {
fn from_fontconfig(weight: i32) -> Self {
const MAP: &[(i32, i32)] = &[
(0, 0),
(100, 0),
(200, 40),
(300, 50),
(350, 55),
(380, 75),
(400, 80),
(500, 100),
(600, 180),
(700, 200),
(800, 205),
(900, 210),
(950, 215),
];
for i in 1..MAP.len() {
let (ot_b, fc_b) = MAP[i];
if weight == fc_b {
return Self::new(ot_b as f32);
}
if weight < fc_b {
let weight = weight as f32;
let fc_b = fc_b as f32;
let ot_b = ot_b as f32;
let (ot_a, fc_a) = MAP[i - 1];
let fc_a = fc_a as f32;
let ot_a = ot_a as f32;
let t = (weight - fc_a) / (fc_b - fc_a);
return Self::new(ot_a + (ot_b - ot_a) * t);
}
}
Self::EXTRA_BLACK
}
}
impl FromFontconfig for FontWidth {
fn from_fontconfig(width: i32) -> Self {
match width {
50 => Self::ULTRA_CONDENSED,
63 => Self::EXTRA_CONDENSED,
75 => Self::CONDENSED,
87 => Self::SEMI_CONDENSED,
100 => Self::NORMAL,
113 => Self::SEMI_EXPANDED,
125 => Self::EXPANDED,
150 => Self::EXTRA_EXPANDED,
200 => Self::ULTRA_EXPANDED,
_ => Self::from_ratio(width as f32 / 100.0),
}
}
}
impl FromFontconfig for FontStyle {
fn from_fontconfig(slant: i32) -> Self {
match slant {
100 => Self::Italic,
110 => Self::Oblique(None),
_ => Self::Normal,
}
}
}
#[cfg(test)]
mod tests {
use super::FromFontconfig;
use crate::{FontStyle, FontWeight, FontWidth};
use alloc::string::ToString;
#[test]
fn fontwidth_from_fontconfig() {
fn check_fc(fc: i32, s: &str) {
let fs = FontWidth::from_fontconfig(fc);
assert_eq!(s, fs.to_string());
}
check_fc(50, "ultra-condensed");
check_fc(63, "extra-condensed");
check_fc(75, "condensed");
check_fc(87, "semi-condensed");
check_fc(100, "normal");
check_fc(113, "semi-expanded");
check_fc(125, "expanded");
check_fc(150, "extra-expanded");
check_fc(200, "ultra-expanded");
}
#[test]
fn fontstyle_from_fontconfig() {
fn check_fc(fc: i32, s: &str) {
let fs = FontStyle::from_fontconfig(fc);
assert_eq!(s, fs.to_string());
}
check_fc(0, "normal");
check_fc(100, "italic");
check_fc(110, "oblique");
}
#[test]
fn fontweight_from_fontconfig_interpolates_monotonically() {
let demilight = FontWeight::from_fontconfig(55);
assert!(demilight > FontWeight::LIGHT);
assert!(demilight < FontWeight::NORMAL);
let book = FontWeight::from_fontconfig(75);
assert!(book > demilight);
assert!(book < FontWeight::NORMAL);
let extrablack = FontWeight::from_fontconfig(215);
assert!(extrablack > FontWeight::BLACK);
}
}