freetype/
library.rs

1use core::ptr::null_mut;
2use libc::{self, c_long, c_void, size_t};
3use {Face, FtResult, Stroker};
4use ffi;
5use Nul;
6
7extern "C" fn alloc_library(_memory: ffi::FT_Memory, size: c_long) -> *mut c_void {
8    unsafe { libc::malloc(size as size_t) }
9}
10
11extern "C" fn free_library(_memory: ffi::FT_Memory, block: *mut c_void) {
12    unsafe { libc::free(block) }
13}
14
15extern "C" fn realloc_library(_memory: ffi::FT_Memory,
16                              _cur_size: c_long,
17                              new_size: c_long,
18                              block: *mut c_void) -> *mut c_void {
19    unsafe { libc::realloc(block, new_size as size_t) }
20}
21
22#[repr(u32)]
23#[derive(Copy, Clone)]
24pub enum LcdFilter {
25    LcdFilterNone    = ffi::FT_LCD_FILTER_NONE,
26    LcdFilterDefault = ffi::FT_LCD_FILTER_DEFAULT,
27    LcdFilterLight   = ffi::FT_LCD_FILTER_LIGHT,
28    LcdFilterLegacy  = ffi::FT_LCD_FILTER_LEGACY,
29}
30
31static mut MEMORY: ffi::FT_MemoryRec = ffi::FT_MemoryRec {
32    user: 0 as *mut c_void,
33    alloc: alloc_library,
34    free: free_library,
35    realloc: realloc_library,
36};
37
38pub struct Library {
39    raw: ffi::FT_Library
40}
41
42impl Library {
43    /// This function is used to create a new FreeType library instance and add the default
44    /// modules. It returns a struct encapsulating the freetype library. The library is correctly
45    /// discarded when the struct is dropped.
46    pub fn init() -> FtResult<Self> { unsafe {
47        let mut raw = null_mut();
48        ::error::from_ftret(ffi::FT_New_Library(&mut MEMORY, &mut raw))?;
49        ffi::FT_Add_Default_Modules(raw);
50        Ok(Library { raw })
51    } }
52
53    /// Open a font file using its pathname. `face_index` should be 0 if there is only 1 font
54    /// in the file.
55    pub fn new_face<P>(&self, path: P, face_index: isize) -> FtResult<Face<'static>>
56      where P: AsRef<Nul<u8>> { unsafe {
57        let mut face = null_mut();
58        ::error::from_ftret(ffi::FT_New_Face(self.raw, path.as_ref().as_ptr() as *const _, face_index as ffi::FT_Long, &mut face))?;
59        Ok(Face::from_raw(self.raw, face))
60    } }
61
62    pub fn new_stroker(&self) -> FtResult<Stroker> { unsafe {
63        let mut stroker = null_mut();
64        ::error::from_ftret(ffi::FT_Stroker_New(self.raw, &mut stroker))?;
65        Ok(Stroker::from_raw(self.raw, stroker))
66    } }
67
68    /// Similar to `new_face`, but loads file data from a byte array in memory
69    pub fn new_memory_face<'a>(&self, buffer: &'a [u8], face_index: isize) -> FtResult<Face<'a>> { unsafe {
70        let mut face = null_mut();
71        ::error::from_ftret(ffi::FT_New_Memory_Face(self.raw, buffer.as_ptr(), buffer.len() as ffi::FT_Long,
72                                                    face_index as ffi::FT_Long, &mut face))?;
73        Ok(Face::from_raw(self.raw, face))
74    } }
75
76    pub fn set_lcd_filter(&self, lcd_filter: LcdFilter) -> FtResult<()> {
77        ::error::from_ftret(unsafe { ffi::FT_Library_SetLcdFilter(self.raw, lcd_filter as u32) })
78    }
79
80    /// Get the underlying library object
81    pub fn raw(&self) -> ffi::FT_Library { self.raw }
82}
83
84impl Drop for Library {
85    fn drop(&mut self) {
86        ::error::from_ftret(unsafe { ffi::FT_Done_Library(self.raw) }).expect("Failed to drop library");
87    }
88}