stevenkhan's picture
Upload spectral-font/src/font.rs
1cb48ad verified
use std::sync::Arc;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum FontStyle {
Regular = 0,
Bold = 1,
Italic = 2,
BoldItalic = 3,
}
impl Default for FontStyle {
fn default() -> Self { FontStyle::Regular }
}
pub struct Font {
pub id: u32,
pub data: Arc<Vec<u8>>,
pub index: u32,
pub style: FontStyle,
pub family_name: String,
pub rasterizer: fontdue::Font,
}
impl Font {
pub fn from_bytes(id: u32, data: Arc<Vec<u8>>, index: u32, style: FontStyle) -> Option<Self> {
let settings = fontdue::FontSettings {
collection_index: index,
scale: 40.0,
load_substitutions: true,
};
let rasterizer = fontdue::Font::from_bytes(&**data, settings).ok()?;
let family_name = format!("Font-{}", id);
Some(Self { id, data, index, style, family_name, rasterizer })
}
pub fn rasterize_glyph(&self, glyph_id: u16, px: f32) -> (fontdue::Metrics, Vec<u8>) {
self.rasterizer.rasterize_indexed(glyph_id, px)
}
pub fn lookup_glyph(&self, ch: char) -> u16 {
self.rasterizer.lookup_glyph_index(ch)
}
}
pub struct FontFamily {
pub name: String,
pub fonts: [Option<Font>; 4],
}
impl FontFamily {
pub fn new(name: &str) -> Self {
Self { name: name.to_string(), fonts: [None, None, None, None] }
}
pub fn add_font(&mut self, font: Font) {
self.fonts[font.style as usize] = Some(font);
}
pub fn get_font(&self, style: FontStyle) -> Option<&Font> {
self.fonts[style as usize].as_ref()
.or_else(|| self.fonts[FontStyle::Bold as usize].as_ref())
.or_else(|| self.fonts[FontStyle::Italic as usize].as_ref())
.or_else(|| self.fonts[FontStyle::Regular as usize].as_ref())
}
}