use std::rc::Rc;
use std::cell::RefCell;
use std::mem;
use std::vec::Vec;
use std::ffi::{CString, CStr};
use libc::{c_float, c_uint, size_t};
use std::str;
use traits::{Drawable, Wrappable};
use graphics::{RenderTarget, Font, FloatRect,
Color, Transform, rc, TextStyle, RenderStates};
use sfml_types::Vector2f;
use ffi::graphics::text as ffi;
pub struct Text {
text: *mut ffi::sfText,
string_length: u32,
font: Option<Rc<RefCell<Font>>>
}
impl Text {
pub fn new() -> Option<Text> {
let text = unsafe { ffi::sfText_create() };
if text.is_null() {
None
} else {
Some(Text {
text: text,
string_length: 0,
font: None
})
}
}
pub fn new_init(string: &str,
font: Rc<RefCell<Font>>,
character_size: u32) ->Option<Text> {
let text = unsafe { ffi::sfText_create() };
if text.is_null() {
None
} else {
let c_str = CString::new(string.as_bytes()).unwrap().as_ptr();
unsafe {
ffi::sfText_setString(text, c_str);
ffi::sfText_setFont(text, (*font).borrow().unwrap());
ffi::sfText_setCharacterSize(text, character_size as c_uint)
}
Some(Text {
text: text,
string_length: string.len() as u32,
font: Some(font)
})
}
}
pub fn clone_opt(&self) -> Option<Text> {
let sp = unsafe { ffi::sfText_copy(self.text) };
if sp.is_null() {
None
} else {
Some(Text {
text: self.text,
string_length: self.string_length as u32,
font: self.font.clone()
})
}
}
pub fn set_string(&mut self, string: &str) {
let c_str = CString::new(string.as_bytes()).unwrap().as_ptr();
unsafe {
ffi::sfText_setString(self.text, c_str)
}
self.string_length = string.len() as u32
}
pub fn get_string(&self) -> String {
unsafe {
let string = ffi::sfText_getString(self.text);
str::from_utf8(CStr::from_ptr(string).to_bytes_with_nul()).unwrap().to_string()
}
}
pub fn get_unicode_string(&self) -> Vec<u32> {
let string: *const u32 = unsafe {
ffi::sfText_getUnicodeString(self.text)
};
let string_slice: &[u32] = unsafe {
::std::slice::from_raw_parts(string, self.string_length as usize)
};
let result = string_slice.to_vec();
result
}
pub fn get_character_size(&self) -> u32 {
unsafe {
ffi::sfText_getCharacterSize(self.text) as u32
}
}
pub fn set_font(&mut self, font: Rc<RefCell<Font>>) {
unsafe {
ffi::sfText_setFont(self.text, (*font).borrow().unwrap())
}
self.font = Some(font);
}
pub fn set_rotation(&mut self, angle: f32) {
unsafe {
ffi::sfText_setRotation(self.text, angle as c_float)
}
}
pub fn get_rotation(&self) -> f32 {
unsafe {
ffi::sfText_getRotation(self.text) as f32
}
}
pub fn rotate(&mut self, angle: f32) {
unsafe {
ffi::sfText_rotate(self.text, angle as c_float)
}
}
pub fn set_style(&mut self, style: TextStyle) {
unsafe {
ffi::sfText_setStyle(self.text, style as u32)
}
}
pub fn set_character_size(&mut self, size: u32) {
unsafe {
ffi::sfText_setCharacterSize(self.text, size as c_uint)
}
}
pub fn get_style(&self) -> TextStyle {
unsafe { ffi::sfText_getStyle(self.text) }
}
pub fn get_font(&self) -> Option<Rc<RefCell<Font>>> {
self.font.clone()
}
pub fn set_color(&mut self, color: &Color) {
unsafe {
ffi::sfText_setColor(self.text, *color)
}
}
pub fn get_color(&self) -> Color {
unsafe {
ffi::sfText_getColor(self.text)
}
}
pub fn scale(&mut self, factors: &Vector2f) {
unsafe {
ffi::sfText_scale(self.text, *factors)
}
}
pub fn scale2f(&mut self, factor_x: f32, factor_y: f32) {
unsafe {
ffi::sfText_scale(self.text, Vector2f::new(factor_x, factor_y))
}
}
pub fn set_scale(&mut self, scale: &Vector2f) {
unsafe {
ffi::sfText_setScale(self.text, *scale)
}
}
pub fn set_scale2f(&mut self, scale_x: f32, scale_y: f32) {
unsafe {
ffi::sfText_setScale(self.text, Vector2f::new(scale_x, scale_y))
}
}
pub fn move_(&mut self, offset: &Vector2f) {
unsafe {
ffi::sfText_move(self.text, *offset)
}
}
pub fn move2f(&mut self, offset_x: f32, offset_y: f32) {
unsafe {
ffi::sfText_move(self.text, Vector2f::new(offset_x, offset_y))
}
}
pub fn set_position(&mut self, position: &Vector2f) {
unsafe {
ffi::sfText_setPosition(self.text, *position)
}
}
pub fn set_position2f(&mut self, x: f32, y: f32) {
unsafe {
ffi::sfText_setPosition(self.text, Vector2f::new(x, y))
}
}
pub fn set_origin(&mut self, origin: &Vector2f) {
unsafe {
ffi::sfText_setOrigin(self.text, *origin)
}
}
pub fn set_origin2f(&mut self, x: f32, y: f32) {
unsafe {
ffi::sfText_setOrigin(self.text, Vector2f::new(x, y))
}
}
pub fn get_scale(&self) -> Vector2f {
unsafe {
ffi::sfText_getScale(self.text)
}
}
pub fn get_origin(&self) -> Vector2f {
unsafe {
ffi::sfText_getOrigin(self.text)
}
}
pub fn find_character_pos(&self, index: u64) -> Vector2f {
unsafe {
ffi::sfText_findCharacterPos(self.text, index as size_t)
}
}
pub fn get_position(&self) -> Vector2f {
unsafe {
ffi::sfText_getPosition(self.text)
}
}
pub fn get_local_bounds(&self) -> FloatRect {
unsafe {
ffi::sfText_getLocalBounds(self.text)
}
}
pub fn get_global_bounds(&self) -> FloatRect {
unsafe {
ffi::sfText_getGlobalBounds(self.text)
}
}
pub fn set_unicode_string(&mut self, string: Vec<u32>) {
unsafe {
self.string_length = string.len() as u32;
ffi::sfText_setUnicodeString(self.text, string.as_ptr())
}
}
pub fn get_transform(&self) -> Transform {
unsafe {
ffi::sfText_getTransform(self.text)
}
}
pub fn get_inverse_transform(&self) -> Transform {
unsafe {
ffi::sfText_getInverseTransform(self.text)
}
}
}
impl Clone for Text{
fn clone(&self) -> Text {
let sp = unsafe { ffi::sfText_copy(self.text) };
if sp.is_null() {
panic!("Not enough memory to clone Text")
} else {
Text {
text: self.text,
string_length: self.string_length,
font: self.font.clone()
}
}
}
}
impl Wrappable<*mut ffi::sfText> for Text {
fn wrap(text: *mut ffi::sfText) -> Text {
Text {
text: text,
string_length: 0,
font: None
}
}
fn unwrap(&self) -> *mut ffi::sfText {
self.text
}
}
impl Drawable for Text {
fn draw<RT:RenderTarget>(&self,
render_target: &mut RT,
render_states: &mut RenderStates) {
render_target.draw_text(self, render_states)
}
}
impl Drop for Text {
fn drop(&mut self) {
unsafe {
ffi::sfText_destroy(self.text);
}
}
}