use std::mem::size_of;
use rocketsplash_formats::{AllocationTracker, GlyphData};
use crate::font::RuntimeGlyph;
use crate::Error;
pub(super) fn convert_glyph(
tracker: &mut AllocationTracker,
glyph: GlyphData,
) -> Result<RuntimeGlyph, Error> {
let cell_count = (glyph.width as usize)
.checked_mul(glyph.height as usize)
.ok_or_else(|| Error::InvalidFormat {
message: format!("Glyph dimensions {}x{} overflow", glyph.width, glyph.height),
})?;
let chars: Vec<char> = glyph.chars.chars().collect();
if chars.len() != cell_count {
return Err(Error::InvalidFormat {
message: format!(
"Glyph char count {} does not match {}x{}",
chars.len(),
glyph.width,
glyph.height
),
});
}
if let Some(ref opacity) = glyph.opacity {
if opacity.len() != cell_count {
return Err(Error::InvalidFormat {
message: format!(
"Glyph opacity length {} does not match {}x{}",
opacity.len(),
glyph.width,
glyph.height
),
});
}
}
let char_bytes = chars.len() * size_of::<char>();
let opacity_bytes = glyph.opacity.as_ref().map(|o| o.len()).unwrap_or(0);
tracker
.reserve(char_bytes + opacity_bytes)
.map_err(|message| Error::InvalidFormat { message })?;
Ok(RuntimeGlyph {
width: glyph.width as usize,
height: glyph.height as usize,
chars,
opacity: glyph.opacity,
})
}