use libc::{c_uint, size_t};
use std::ptr;
use std::ffi::CString;
use std::io::{Read, Seek};
use traits::Wrappable;
use graphics::{RenderWindow, Image, IntRect};
use sfml_types::Vector2u;
use system::inputstream::InputStream;
use window::Window;
use sfml_types::sfBool;
use csfml_graphics_sys as ffi;
pub struct Texture {
texture: *mut ffi::sfTexture,
dropable: bool
}
impl Texture {
pub fn new(width: u32, height: u32) -> Option<Texture> {
let tex = unsafe { ffi::sfTexture_create(width as c_uint,
height as c_uint) };
if tex.is_null() {
None
} else {
Some(Texture {
texture: tex,
dropable: true
})
}
}
pub fn new_from_memory(mem: &[u8], area: &IntRect) -> Option<Texture> {
let tex = unsafe { ffi::sfTexture_createFromMemory(&mem[0],
mem.len() as size_t,
area) };
if tex.is_null() {
None
} else {
Some(Texture {
texture: tex,
dropable: true
})
}
}
pub fn new_from_stream<T: Read + Seek>(stream: &mut T, area: &mut IntRect) -> Option<Texture> {
let mut input_stream = InputStream::new(stream);
let tex = unsafe {
ffi::sfTexture_createFromStream(&mut input_stream.0, area)
};
if tex.is_null() {
None
} else {
Some(Texture {
texture: tex,
dropable: true
})
}
}
pub fn new_from_file(filename: &str) -> Option<Texture> {
let c_str = CString::new(filename.as_bytes()).unwrap().as_ptr();
let tex = unsafe {
ffi::sfTexture_createFromFile(c_str as *mut i8, ptr::null())
};
if tex.is_null() {
None
} else {
Some(Texture {
texture: tex,
dropable: true
})
}
}
pub fn new_from_file_with_rect(filename: &str,
area: &IntRect) -> Option<Texture> {
let c_str = CString::new(filename.as_bytes()).unwrap().as_ptr();
let tex = unsafe {
ffi::sfTexture_createFromFile(c_str as *mut i8, area)
};
if tex.is_null() {
None
} else {
Some(Texture {
texture: tex,
dropable: true
})
}
}
pub fn clone_opt(&self) -> Option<Texture> {
let tex = unsafe { ffi::sfTexture_copy(self.texture) };
if tex.is_null() {
None
} else {
Some(Texture {
texture: tex,
dropable: true
})
}
}
pub fn new_from_image_with_rect(image: &Image,
area: &IntRect) -> Option<Texture> {
let tex = unsafe { ffi::sfTexture_createFromImage(image.unwrap(),
area) };
if tex.is_null() {
None
} else {
Some(Texture {
texture: tex,
dropable: true
})
}
}
pub fn new_from_image(image: &Image) -> Option<Texture> {
let tex = unsafe { ffi::sfTexture_createFromImage(image.unwrap(),
ptr::null()) };
if tex.is_null() {
None
} else {
Some(Texture {
texture: tex,
dropable: true
})
}
}
pub fn get_size(&self) -> Vector2u {
unsafe {
ffi::sfTexture_getSize(self.texture)
}
}
pub fn update_from_window(&mut self,
window: &Window,
x: u32,
y: u32) {
unsafe {
ffi::sfTexture_updateFromWindow(self.texture,
window.unwrap(),
x as c_uint,
y as c_uint)
}
}
pub fn update_from_render_window(&mut self,
render_window: &RenderWindow,
x: u32,
y: u32) {
unsafe {
ffi::sfTexture_updateFromRenderWindow(self.texture,
render_window.unwrap(),
x as c_uint,
y as c_uint)
}
}
pub fn update_from_image(&mut self,
image: &Image,
x: u32,
y: u32) {
unsafe {
ffi::sfTexture_updateFromImage(self.texture,
image.unwrap(),
x as c_uint,
y as c_uint)
}
}
pub fn update_from_pixels(&mut self,
pixels: &[u8],
width: u32,
height: u32,
x: u32,
y: u32) {
unsafe {
ffi::sfTexture_updateFromPixels(self.texture,
pixels.as_ptr(),
width as c_uint,
height as c_uint,
x as c_uint,
y as c_uint)
}
}
pub fn set_smooth(&mut self, smooth: bool) {
unsafe {
ffi::sfTexture_setSmooth(self.texture, sfBool::from_bool(smooth))
}
}
pub fn is_smooth(&self) -> bool {
unsafe { ffi::sfTexture_isSmooth(self.texture) }.to_bool()
}
pub fn set_repeated(&mut self, repeated: bool) {
unsafe {
ffi::sfTexture_setRepeated(self.texture, sfBool::from_bool(repeated))
}
}
pub fn is_repeated(&self) -> bool {
unsafe { ffi::sfTexture_isRepeated(self.texture) }.to_bool()
}
pub fn bind(&mut self) {
unsafe {
ffi::sfTexture_bind(self.texture)
}
}
pub fn get_maximum_size() -> u32 {
unsafe {
ffi::sfTexture_getMaximumSize() as u32
}
}
pub fn copy_to_image(&self) -> Option<Image> {
let img = unsafe {ffi::sfTexture_copyToImage(self.texture)};
if img.is_null() {
None
} else {
Some(Wrappable::wrap(img))
}
}
}
impl Clone for Texture {
fn clone(&self) -> Texture {
let tex = unsafe { ffi::sfTexture_copy(self.texture) };
if tex.is_null() {
panic!("Not enough memory to clone Texture")
} else {
Texture {
texture: tex,
dropable: true
}
}
}
}
impl Wrappable<*mut ffi::sfTexture> for Texture {
fn unwrap(&self) -> *mut ffi::sfTexture {
self.texture
}
fn wrap(texture: *mut ffi::sfTexture) -> Texture {
Texture {
texture: texture,
dropable: false
}
}
}
impl Drop for Texture {
fn drop(&mut self) {
if self.dropable {
unsafe {
ffi::sfTexture_destroy(self.texture)
}
}
}
}