use libc::{c_uint, size_t};
use std::ffi::CString;
use traits::Wrappable;
use graphics::{Texture, Glyph};
use sfml_types::sfBool;
use csfml_graphics_sys as ffi;
use std::io::{Read, Seek};
use system::inputstream::InputStream;
pub struct Font {
font: *mut ffi::sfFont,
dropable: bool
}
impl Font {
pub fn new_from_file(filename: &str) -> Option<Font> {
let c_str = CString::new(filename.as_bytes()).unwrap();
let fnt = unsafe {
ffi::sfFont_createFromFile(c_str.as_ptr())
};
if fnt.is_null() {
None
} else {
Some(Font {
font: fnt,
dropable: true
})
}
}
pub fn new_from_stream<T: Read + Seek>(stream: &mut T) -> Option<Font> {
let mut input_stream = InputStream::new(stream);
let fnt = unsafe {
ffi::sfFont_createFromStream(&mut input_stream.0)
};
if fnt.is_null() {
None
} else {
Some(Font {
font: fnt,
dropable: true
})
}
}
pub fn new_from_memory(memory: &[u8]) -> Option<Font> {
let fnt = unsafe {
ffi::sfFont_createFromMemory(&memory[0], memory.len() as size_t)
};
if fnt.is_null() {
None
} else {
Some(Font {
font: fnt,
dropable: true
})
}
}
pub fn clone_opt(&self) -> Option<Font> {
let fnt = unsafe {ffi::sfFont_copy(self.font)};
if fnt.is_null() {
None
} else {
Some(Font {
font: fnt,
dropable: true
})
}
}
pub fn get_kerning(&self,
first: u32,
second: u32,
character_size: u32) -> i32 {
unsafe {
ffi::sfFont_getKerning(self.font,
first,
second,
character_size as c_uint) as i32
}
}
pub fn get_line_spacing(&self, character_size: u32) -> i32 {
unsafe {
ffi::sfFont_getLineSpacing(self.font,
character_size as c_uint) as i32
}
}
pub fn get_texture(&self, character_size: u32) -> Option<Texture> {
let tex = unsafe {ffi::sfFont_getTexture(self.font,
character_size as c_uint)};
if tex.is_null() {
None
} else {
Some(Wrappable::wrap(tex))
}
}
pub fn get_glyph(&self,
codepoint: u32,
character_size: u32,
bold: bool) -> Glyph {
unsafe {
ffi::sfFont_getGlyph(self.font, codepoint, character_size as c_uint, sfBool::from_bool(bold))
}
}
}
impl Clone for Font {
fn clone(&self) -> Font {
let fnt = unsafe {ffi::sfFont_copy(self.font)};
if fnt.is_null() {
panic!("Not enough memory to clone Font")
} else {
Font {
font: fnt,
dropable: true
}
}
}
}
impl Wrappable<*mut ffi::sfFont> for Font {
fn wrap(font: *mut ffi::sfFont) -> Font {
Font {
font: font,
dropable: false
}
}
fn unwrap(&self) -> *mut ffi::sfFont {
self.font
}
}
impl Drop for Font {
fn drop(&mut self) {
if self.dropable {
unsafe {
ffi::sfFont_destroy(self.font)
}
}
}
}