diff options
author | Joe Wilm <joe@jwilm.com> | 2016-02-21 19:44:54 -0800 |
---|---|---|
committer | Joe Wilm <joe@jwilm.com> | 2016-02-21 19:45:35 -0800 |
commit | 5040c44f670ab1ce51faf3ae588002f7b4c0ffca (patch) | |
tree | fe5da8dc8f5f025a109464a225f271f9eedf0c03 /src | |
parent | 32bac943433610434f7d504114d6d409c8a698af (diff) | |
download | r-alacritty-5040c44f670ab1ce51faf3ae588002f7b4c0ffca.tar.gz r-alacritty-5040c44f670ab1ce51faf3ae588002f7b4c0ffca.tar.bz2 r-alacritty-5040c44f670ab1ce51faf3ae588002f7b4c0ffca.zip |
Implement very basic glyph rasterization
There are several assumptions made at this point and very little (no)
error handling done.
Diffstat (limited to 'src')
-rw-r--r-- | src/list_fonts.rs | 19 | ||||
-rw-r--r-- | src/main.rs | 1 | ||||
-rw-r--r-- | src/text.rs | 81 |
3 files changed, 101 insertions, 0 deletions
diff --git a/src/list_fonts.rs b/src/list_fonts.rs index c418bc02..c7cd60ca 100644 --- a/src/list_fonts.rs +++ b/src/list_fonts.rs @@ -69,12 +69,31 @@ pub struct Variant { index: usize, } +impl Variant { + #[inline] + pub fn filepath(&self) -> &::std::path::Path { + self.file.as_path() + } +} + #[derive(Debug)] pub struct Family { name: String, variants: Vec<Variant>, } +impl Family { + #[inline] + pub fn name(&self) -> &str { + &self.name[..] + } + + #[inline] + pub fn variants(&self) -> &[Variant] { + &self.variants[..] + } +} + static FILE: &'static [u8] = b"file\0"; static FAMILY: &'static [u8] = b"family\0"; static INDEX: &'static [u8] = b"index\0"; diff --git a/src/main.rs b/src/main.rs index 66be9b34..7356bd36 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ extern crate freetype; extern crate libc; mod list_fonts; +mod text; fn main() { println!("Hello, world!"); diff --git a/src/text.rs b/src/text.rs new file mode 100644 index 00000000..5694e2ce --- /dev/null +++ b/src/text.rs @@ -0,0 +1,81 @@ +use list_fonts::get_font_families; + +use freetype::Library; +use freetype::Face; +use freetype; + +/// Rasterizes glyphs for a single font face. +pub struct Rasterizer { + face: Face<'static>, + library: Library, +} + +#[inline] +fn to_freetype_26_6(f: f32) -> isize { + ((1i32 << 6) as f32 * f) as isize +} + +impl Rasterizer { + pub fn new() -> Rasterizer { + let library = Library::init().unwrap(); + + let family = get_font_families().into_iter() + .filter(|f| f.name() == "Inconsolata-dz") + .nth(0).unwrap(); // TODO + + let variant = family.variants().first().unwrap(); + let path = variant.filepath(); + + Rasterizer { + face: library.new_face(path, 0).expect("Create font face"), + library: library, + } + } + + pub fn get_glyph(&self, size: f32, c: char) -> RasterizedGlyph { + // TODO DPI + self.face.set_char_size(to_freetype_26_6(size), 0, 96, 0).unwrap(); + self.face.load_char(c as usize, freetype::face::RENDER).unwrap(); + let glyph = self.face.glyph(); + + RasterizedGlyph { + top: glyph.bitmap_top() as usize, + left: glyph.bitmap_left() as usize, + width: glyph.bitmap().width() as usize, + height: glyph.bitmap().rows() as usize, + buf: glyph.bitmap().buffer().to_vec(), + } + } +} + +#[derive(Debug)] +struct RasterizedGlyph { + width: usize, + height: usize, + top: usize, + left: usize, + buf: Vec<u8>, +} + + +#[cfg(test)] +mod tests { + use super::Rasterizer; + + #[test] + fn create_rasterizer_and_render_glyph() { + let rasterizer = Rasterizer::new(); + let glyph = rasterizer.get_glyph(24., 'U'); + + println!("glyph: {:?}", glyph); + + for j in 0..glyph.height { + for i in 0..glyph.width { + let val = glyph.buf[j * glyph.width + i]; + print!("{}", if val < 122 { " " } else { "%"}); + } + + print!("\n"); + } + } +} |