diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-08-01 00:01:17 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-08-01 00:10:54 +0200 |
| commit | 06dbac6efd98be5a015023c88ed3dbd9a35a4594 (patch) | |
| tree | bb3c75230098bf71d1ac23bbe7184e4ae7a6cef2 /src/font.rs | |
| parent | 064954cf9edbb0201b6184e69978f86e93741008 (diff) | |
Port font handling to fontdock and ttf-parser 🛳
- Use fontdock for indexing fonts and querying
- Typst binary now automatically indexes and uses system fonts in addition to a fixed font folder!
- Removes subsetting support for now (was half-finished anyways, plan is to use harfbuzz for subsetting in the future)
- Adds font width configuration support
Diffstat (limited to 'src/font.rs')
| -rw-r--r-- | src/font.rs | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/font.rs b/src/font.rs new file mode 100644 index 00000000..81a63445 --- /dev/null +++ b/src/font.rs @@ -0,0 +1,69 @@ +//! Font handling. + +use std::cell::RefCell; +use std::ops::Deref; +use std::rc::Rc; +use ttf_parser::Face; +use fontdock::{FontLoader, FontProvider, ContainsChar, FaceFromVec}; + +/// A referenced-count shared font loader backed by a dynamic provider. +pub type SharedFontLoader = Rc<RefCell<FontLoader<Box<DynProvider>>>>; + +/// The dynamic font provider type backing the font loader. +pub type DynProvider = dyn FontProvider<Face=OwnedFace>; + +/// An owned font face. +pub struct OwnedFace { + data: Vec<u8>, + face: Face<'static>, +} + +impl FaceFromVec for OwnedFace { + fn from_vec(vec: Vec<u8>, i: u32) -> Option<Self> { + // The vec's location is stable in memory since we don't touch it and + // it can't be touched from outside this type. + let slice: &'static [u8] = unsafe { + std::slice::from_raw_parts(vec.as_ptr(), vec.len()) + }; + + Some(OwnedFace { + data: vec, + face: Face::from_slice(slice, i).ok()?, + }) + } +} + +impl OwnedFace { + /// The raw face data. + pub fn data(&self) -> &[u8] { + &self.data + } + + /// Encode the text into glyph ids and encode these into a big-endian byte + /// buffer. + pub fn encode_text(&self, text: &str) -> Vec<u8> { + const BYTES_PER_GLYPH: usize = 2; + let mut bytes = Vec::with_capacity(BYTES_PER_GLYPH * text.len()); + for c in text.chars() { + if let Some(glyph) = self.glyph_index(c) { + bytes.push((glyph.0 >> 8) as u8); + bytes.push((glyph.0 & 0xff) as u8); + } + } + bytes + } +} + +impl ContainsChar for OwnedFace { + fn contains_char(&self, c: char) -> bool { + self.glyph_index(c).is_some() + } +} + +impl Deref for OwnedFace { + type Target = Face<'static>; + + fn deref(&self) -> &Self::Target { + &self.face + } +} |
