pub struct FTLibrary {
library: FT_Library,
+ faces: Vec<FT_Face>,
}
impl Drop for FTLibrary {
fn drop(&mut self) {
+ for face in &self.faces {
+ unsafe {
+ FT_Done_Face(*face);
+ }
+ }
if !self.library.is_null() {
unsafe {
FT_Done_FreeType(self.library);
if FT_Init_FreeType(&mut library_ptr) == 0 {
Some(FTLibrary {
library: library_ptr,
+ faces: Vec::new(),
})
} else {
None
pub fn get(&self) -> FT_Library {
self.library
}
- }
-
- pub struct FTOpenArgs {
- args: FT_Open_Args,
- // "args" has a pointer to the CString in "pathname", so it must be kept
- #[allow(dead_code)]
- pathname: Option<CString>,
- }
- impl FTOpenArgs {
- pub fn new_with_path(path: &Path) -> Self {
- unsafe {
- let cstring: CString = CString::from_vec_unchecked(
- path.as_os_str().to_str().unwrap().as_bytes().to_vec(),
- );
- let args = FT_Open_Args {
- flags: FT_OPEN_PATHNAME,
- memory_base: std::ptr::null::<u8>(),
- memory_size: 0,
- pathname: cstring.as_ptr() as *mut i8,
- stream: std::ptr::null_mut::<FT_StreamRec_>(),
- driver: std::ptr::null_mut::<FT_ModuleRec_>(),
- num_params: 0,
- params: std::ptr::null_mut::<FT_Parameter_>(),
- };
-
- FTOpenArgs {
- args,
- pathname: Some(cstring),
- }
- }
- }
-
- #[allow(dead_code)]
- pub fn get_args(&self) -> FT_Open_Args {
- self.args
- }
-
- pub fn get_ptr(&mut self) -> *mut FT_Open_Args {
- &mut self.args as *mut FT_Open_Args
- }
- }
-
- pub struct FTFaces {
- faces: Vec<FT_Face>,
- }
-
- impl Drop for FTFaces {
- fn drop(&mut self) {
- for face in &self.faces {
- unsafe {
- FT_Done_Face(*face);
- }
- }
- }
- }
-
- impl FTFaces {
- pub fn new(library: &FTLibrary, args: &mut FTOpenArgs) -> Result<FTFaces, String> {
- let mut faces = FTFaces { faces: Vec::new() };
+ pub fn init_faces(&mut self, args: &mut FTOpenArgs) -> Result<(), String> {
unsafe {
let mut face: FT_Face = 0 as FT_Face;
// first get number of faces
let mut result = FT_Open_Face(
- library.get(),
+ self.get(),
args.get_ptr(),
-1,
&mut face as *mut *mut FT_FaceRec_,
for i in 0..count {
result = FT_Open_Face(
- library.get(),
+ self.get(),
args.get_ptr(),
i,
&mut face as *mut *mut FT_FaceRec_,
FT_Done_Face(face);
return Err(String::from("Failed to fetch face"));
}
- faces.faces.push(face);
+ self.faces.push(face);
}
}
- Ok(faces)
+ Ok(())
+ }
+
+ #[allow(dead_code)]
+ pub fn drop_faces(&mut self) {
+ for face in &self.faces {
+ unsafe {
+ FT_Done_Face(*face);
+ }
+ }
+ self.faces.clear();
}
pub fn has_char(&self, c: char) -> bool {
false
}
}
+
+ pub struct FTOpenArgs {
+ args: FT_Open_Args,
+ // "args" has a pointer to the CString in "pathname", so it must be kept
+ #[allow(dead_code)]
+ pathname: Option<CString>,
+ }
+
+ impl FTOpenArgs {
+ pub fn new_with_path(path: &Path) -> Self {
+ unsafe {
+ let cstring: CString = CString::from_vec_unchecked(
+ path.as_os_str().to_str().unwrap().as_bytes().to_vec(),
+ );
+ let args = FT_Open_Args {
+ flags: FT_OPEN_PATHNAME,
+ memory_base: std::ptr::null::<u8>(),
+ memory_size: 0,
+ pathname: cstring.as_ptr() as *mut i8,
+ stream: std::ptr::null_mut::<FT_StreamRec_>(),
+ driver: std::ptr::null_mut::<FT_ModuleRec_>(),
+ num_params: 0,
+ params: std::ptr::null_mut::<FT_Parameter_>(),
+ };
+
+ FTOpenArgs {
+ args,
+ pathname: Some(cstring),
+ }
+ }
+ }
+
+ #[allow(dead_code)]
+ pub fn get_args(&self) -> FT_Open_Args {
+ self.args
+ }
+
+ pub fn get_ptr(&mut self) -> *mut FT_Open_Args {
+ &mut self.args as *mut FT_Open_Args
+ }
+ }
}
pub fn font_has_char(c: char, font_path: &Path) -> Result<bool, String> {
- let library = ffi::FTLibrary::new().ok_or_else(|| String::from("Failed to get FTLibrary"))?;
+ let mut library =
+ ffi::FTLibrary::new().ok_or_else(|| String::from("Failed to get FTLibrary"))?;
let mut args = ffi::FTOpenArgs::new_with_path(font_path);
- let faces = ffi::FTFaces::new(&library, &mut args)?;
+ library.init_faces(&mut args)?;
- Ok(faces.has_char(c))
+ Ok(library.has_char(c))
}