use crate::font::Font;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct FontFeature {
pub tag: [u8; 4],
pub value: u32,
}
#[derive(Clone, Copy, Debug)]
pub struct ShapedGlyph {
pub id: u32,
pub cluster: usize,
pub x_advance: f32,
pub x_offset: f32,
pub y_offset: f32,
}
pub fn shape(
font: &Font,
size: f32,
text: &str,
right_to_left: bool,
features: &[FontFeature],
) -> Vec<ShapedGlyph> {
let Ok(font_ref) = harfrust::FontRef::from_index(font.data(), font.face_index()) else {
return Vec::new();
};
let shaper = font
.shaper_data()
.shaper(&font_ref)
.instance(font.shaper_instance())
.build();
let mut buffer = harfrust::UnicodeBuffer::new();
buffer.push_str(text);
buffer.set_direction(if right_to_left {
harfrust::Direction::RightToLeft
} else {
harfrust::Direction::LeftToRight
});
buffer.guess_segment_properties();
let features: Vec<harfrust::Feature> = features
.iter()
.map(|feature| harfrust::Feature::new(harfrust::Tag::new(&feature.tag), feature.value, ..))
.collect();
let output = shaper.shape(buffer, harfrust::ShapeOptions::new().features(&features));
let scale = size / font.units_per_em();
output
.glyph_infos()
.iter()
.zip(output.glyph_positions())
.map(|(info, position)| ShapedGlyph {
id: info.glyph_id,
cluster: info.cluster as usize,
x_advance: position.x_advance as f32 * scale,
x_offset: position.x_offset as f32 * scale,
y_offset: position.y_offset as f32 * scale,
})
.collect()
}