From f27a8005491a61d1372490510dcc045c43ac5754 Mon Sep 17 00:00:00 2001 From: Mika Vatanen Date: Sat, 31 Jul 2021 17:07:24 +0300 Subject: [PATCH] Add documentation --- Cargo.toml | 2 +- examples/ttf2check.rs | 2 +- examples/ttf2mesh.rs | 2 +- src/error.rs | 13 +++++++++- src/glyph.rs | 1 + src/lib.rs | 18 +++++++------- src/ttf.rs | 58 +++++++++++++++++++++++++++---------------- 7 files changed, 62 insertions(+), 34 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ec35d85..88dea2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ttf2mesh" -version = "0.0.2" +version = "0.0.3" edition = "2018" description = "Rust API for ttf2mesh" repository = "https://github.com/blaind/ttf2mesh-rs" diff --git a/examples/ttf2check.rs b/examples/ttf2check.rs index a5c4f4f..8732716 100644 --- a/examples/ttf2check.rs +++ b/examples/ttf2check.rs @@ -26,7 +26,7 @@ fn main() { println!( "- {} = {}", char, - match font.glyph_by_char(char) { + match font.glyph_from_char(char) { Ok(mut glyph) => { let len2dvert = match glyph.to_2d_mesh(ttf2mesh::Quality::Medium) { Ok(mesh) => mesh.vertices_len(), diff --git a/examples/ttf2mesh.rs b/examples/ttf2mesh.rs index 41a487d..3a51b4b 100644 --- a/examples/ttf2mesh.rs +++ b/examples/ttf2mesh.rs @@ -40,7 +40,7 @@ fn main() { for char in utf8_string.chars() { println!("Mesh data char {:?}", char); - let mut glyph = match font.glyph_by_char(char) { + let mut glyph = match font.glyph_from_char(char) { Ok(g) => g, Err(_) => { println!("- can not find glyph in the font file"); diff --git a/src/error.rs b/src/error.rs index f6bee26..fbacd2e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,10 +1,21 @@ +/// Represents an error by the library #[derive(Debug)] pub enum Error { + /// Font could not be loaded. The library doesn't support all font types FontLoadError, + + /// Font could not be exported to an obj file ObjExportError, + + /// Mesh generation failed Glyph2MeshError, + + /// Glyph is not found in the font file GlyphNotFound, - NoCharacterFound, + + /// Quality could not be parsed from input QualityParse, + + /// File to be opened was not found FileNotFound, } diff --git a/src/glyph.rs b/src/glyph.rs index e40461c..ce58682 100644 --- a/src/glyph.rs +++ b/src/glyph.rs @@ -4,6 +4,7 @@ use ttf2mesh_sys as sys; use crate::{mesh::Mesh, Error, Quality}; +/// Represents a glyph in truetype font file. Can be converted to a 2d or 3d mesh pub struct Glyph<'a> { inner: &'a mut sys::ttf_glyph, } diff --git a/src/lib.rs b/src/lib.rs index ef1e3a0..196fb82 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,16 +55,16 @@ mod tests { } #[test] - fn test_get_glyph_by_char() { + fn test_get_glyph_from_char() { let mut font = TTFFile::from_buffer_vec(read_font(None)).unwrap(); let char = "A".chars().next().unwrap(); - let _ = font.glyph_by_char(char).unwrap(); + let _ = font.glyph_from_char(char).unwrap(); } #[test] fn test_to_3d_mesh() { let mut font = TTFFile::from_buffer_vec(read_font(None)).unwrap(); - let mut glyph = font.glyph_by_char("€".chars().next().unwrap()).unwrap(); + let mut glyph = font.glyph_from_char("€".chars().next().unwrap()).unwrap(); let mesh = glyph.to_3d_mesh(Quality::Low, 0.5).unwrap(); let mut sizes = Vec::new(); @@ -96,7 +96,7 @@ mod tests { #[test] fn test_to_2d_mesh() { let mut font = TTFFile::from_buffer_vec(read_font(None)).unwrap(); - let mut glyph = font.glyph_by_char("€".chars().next().unwrap()).unwrap(); + let mut glyph = font.glyph_from_char("€".chars().next().unwrap()).unwrap(); let mut sizes = Vec::new(); let mesh = glyph.to_2d_mesh(Quality::Low).unwrap(); @@ -136,7 +136,7 @@ mod tests { let char = "€".chars().next().unwrap(); b.iter(|| { - let _ = font.glyph_by_char(char).unwrap(); + let _ = font.glyph_from_char(char).unwrap(); }); } @@ -145,7 +145,7 @@ mod tests { let mut font = TTFFile::from_buffer_vec(read_font(None)).unwrap(); let char = "€".chars().next().unwrap(); - let mut glyph = font.glyph_by_char(char).unwrap(); + let mut glyph = font.glyph_from_char(char).unwrap(); b.iter(|| { let _ = glyph.to_3d_mesh(Quality::Low, 0.1).unwrap(); @@ -157,7 +157,7 @@ mod tests { let mut font = TTFFile::from_buffer_vec(read_font(None)).unwrap(); let char = "€".chars().next().unwrap(); - let mut glyph = font.glyph_by_char(char).unwrap(); + let mut glyph = font.glyph_from_char(char).unwrap(); b.iter(|| { let _ = glyph.to_3d_mesh(Quality::High, 0.1).unwrap(); @@ -169,7 +169,7 @@ mod tests { let mut font = TTFFile::from_buffer_vec(read_font(None)).unwrap(); let char = "€".chars().next().unwrap(); - let mut glyph = font.glyph_by_char(char).unwrap(); + let mut glyph = font.glyph_from_char(char).unwrap(); b.iter(|| { let _ = glyph.to_2d_mesh(Quality::Low).unwrap(); @@ -181,7 +181,7 @@ mod tests { let mut font = TTFFile::from_buffer_vec(read_font(None)).unwrap(); let char = "€".chars().next().unwrap(); - let mut glyph = font.glyph_by_char(char).unwrap(); + let mut glyph = font.glyph_from_char(char).unwrap(); b.iter(|| { let _ = glyph.to_2d_mesh(Quality::High).unwrap(); diff --git a/src/ttf.rs b/src/ttf.rs index f06dce3..8468d39 100644 --- a/src/ttf.rs +++ b/src/ttf.rs @@ -6,31 +6,42 @@ use ttf2mesh_sys as sys; use crate::{path_to_cstring, Error, Glyph, Quality}; +/// A decoded TTF file instance +/// +/// Usage - opening a file: +/// ```rust +/// # use ttf2mesh::{TTFFile, Quality}; +/// +/// // from a file +/// let ttf = TTFFile::from_file("./fonts/FiraMono-Medium.ttf").unwrap(); +/// +/// // from a buffer +/// let my_vec = std::fs::read("./fonts/FiraMono-Medium.ttf").unwrap(); +/// let mut ttf = TTFFile::from_buffer_vec(my_vec).unwrap(); +/// +/// // how many fonts? +/// assert_eq!(ttf.glyph_count(), 1485); +/// +/// // export all glyphs as 2d meshes to a .obj file +/// ttf.export_to_obj("/dev/null", Quality::Low).unwrap(); +/// +/// // generate 2d mesh for a glyph +/// let mut glyph = ttf.glyph_from_char('€').unwrap(); +/// let mesh = glyph.to_2d_mesh(Quality::Medium).unwrap(); +/// assert_eq!(mesh.vertices_len(), 56); +/// assert_eq!(mesh.iter_vertices().next().unwrap().value(), (0.555, 0.656)); +/// +/// assert_eq!(mesh.faces_len(), 54); +/// assert_eq!(mesh.iter_faces().next().unwrap().value(), (53, 52, 5)); +/// ``` pub struct TTFFile { ttf: *mut sys::ttf_file, } impl TTFFile { - //pub fn from_system_font() -> Result { - /* - // list all system fonts by filename mask: - - ttf_t **list = ttf_list_system_fonts("DejaVuSans*|Ubuntu*|FreeSerif*|Arial*|Cour*"); - if (list == NULL) return false; // no memory in system - if (list[0] == NULL) return false; // no fonts were found - - // load the first font from the list - - ttf_load_from_file(list[0]->filename, &font, false); - ttf_free_list(list); - if (font == NULL) return false; - - printf("font \"%s\" loaded\n", font->names.full_name); - return true; - */ - //} - - // data needs to be mutable (modified by ttf_*), hence vec + /// Load TTF font from a memory buffer + /// + /// Has to take ownership since the buffer is being modified at runtime pub fn from_buffer_vec(data: Vec) -> Result { let mut ttf = MaybeUninit::uninit(); let error = unsafe { @@ -44,6 +55,7 @@ impl TTFFile { Self::load(ttf, error) } + /// Load TTF font from a file pub fn from_file>(path: P) -> Result { if !Path::new(path.as_ref().as_os_str()).exists() { return Err(Error::FileNotFound); @@ -68,6 +80,7 @@ impl TTFFile { }) } + /// Export all glyphs to a .obj -file pub fn export_to_obj>( &mut self, obj_path: P, @@ -86,7 +99,8 @@ impl TTFFile { Ok(()) } - pub fn glyph_by_char<'a>(&'a mut self, char: char) -> Result, Error> { + /// Get a glyph for a character + pub fn glyph_from_char<'a>(&'a mut self, char: char) -> Result, Error> { let mut bytes = [0; 2]; char.encode_utf16(&mut bytes); @@ -99,10 +113,12 @@ impl TTFFile { self.glyph_by_index(index.try_into().unwrap()) } + /// Total count of glyphs in a ttf file pub fn glyph_count(&self) -> usize { unsafe { *self.ttf }.nglyphs.try_into().unwrap() } + /// Get a glyph by its index. See also [`glyph_from_char`] pub fn glyph_by_index<'a>(&'a mut self, index: usize) -> Result, Error> { let glyphs = unsafe { slice::from_raw_parts_mut((*self.ttf).glyphs, self.glyph_count()) };