1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
use std::ffi::{ CString, OsStr }; use std::ptr::null_mut; use libc::{ self, c_void, c_long, size_t }; use { Face, FtResult, Error }; use ffi::{ self, FT_Alloc_Func, FT_Free_Func, FT_Realloc_Func }; extern "C" fn alloc_library(_memory: ffi::FT_Memory, size: c_long) -> *mut c_void { unsafe { libc::malloc(size as size_t) } } extern "C" fn free_library(_memory: ffi::FT_Memory, block: *mut c_void) { unsafe { libc::free(block) } } extern "C" fn realloc_library(_memory: ffi::FT_Memory, _cur_size: c_long, new_size: c_long, block: *mut c_void) -> *mut c_void { unsafe { libc::realloc(block, new_size as size_t) } } static mut MEMORY: ffi::FT_MemoryRec = ffi::FT_MemoryRec { user: 0 as *mut c_void, alloc: alloc_library, free: free_library, realloc: realloc_library }; pub struct Library { raw: ffi::FT_Library } impl Library { pub fn init() -> FtResult<Self> { let mut raw = null_mut(); let err = unsafe { ffi::FT_New_Library(&mut MEMORY, &mut raw) }; if err == ffi::FT_Err_Ok { unsafe { ffi::FT_Add_Default_Modules(raw); } Ok(Library { raw: raw }) } else { Err(err.into()) } } pub fn new_face<P>(&self, path: P, face_index: isize) -> FtResult<Face<'static>> where P: AsRef<OsStr> { let mut face = null_mut(); let path = try!(path.as_ref() .to_str() .and_then(|s| CString::new(s).ok()) .ok_or(Error::InvalidPath)); let err = unsafe { ffi::FT_New_Face(self.raw, path.as_ptr() as *const _, face_index as ffi::FT_Long, &mut face) }; if err == ffi::FT_Err_Ok { Ok(Face::from_raw(self.raw, face)) } else { Err(err.into()) } } pub fn new_memory_face<'a>(&self, buffer: &'a [u8], face_index: isize) -> FtResult<Face<'a>> { let mut face = null_mut(); let err = unsafe { ffi::FT_New_Memory_Face(self.raw, buffer.as_ptr(), buffer.len() as ffi::FT_Long, face_index as ffi::FT_Long, &mut face) }; if err == ffi::FT_Err_Ok { Ok(Face::from_raw(self.raw, face)) } else { Err(err.into()) } } pub fn raw(&self) -> ffi::FT_Library { self.raw } pub fn get_memory(&self) -> &ffi::FT_MemoryRec { unsafe { &MEMORY } } pub fn new_memory(&self, alloc: Option<FT_Alloc_Func>, free: Option<FT_Free_Func>, realloc: Option<FT_Realloc_Func>, user: Option<*mut c_void>) { unsafe { MEMORY = ffi::FT_MemoryRec { user: user.unwrap_or(0 as *mut c_void), alloc: alloc.unwrap_or(alloc_library), free: free.unwrap_or(free_library), realloc: realloc.unwrap_or(realloc_library) }; } } } impl Drop for Library { fn drop(&mut self) { let err = unsafe { ffi::FT_Done_Library(self.raw) }; if err != ffi::FT_Err_Ok { panic!("Failed to drop library") } } }