use crate::canvas::Color;
use fontconfig::Fontconfig;
use sfml::graphics::Image as Img;
use std::path::Path;
#[derive(Debug, Clone)]
pub struct FontHandler {
font_path: String,
}
impl FontHandler {
pub fn custom(font_path: String) -> Option<Self> {
let path = Path::new(&font_path);
if path.is_dir() || path.exists() {
let mut ret = String::new();
match path.to_str() {
Some(val) => ret = val.to_string(),
None => return None,
}
Some(Self { font_path: ret }) } else {
return None;
}
}
#[cfg(target_os = "linux")]
pub fn find_fonts(f: String) -> Option<Self> {
let mut ret = String::new();
if let Some(fc) = Fontconfig::new() {
match fc.find(f.as_str(), None) {
Some(val) => {
match val.path.to_str() {
Some(s) => ret = s.to_string(),
None => ret = "unable to retrieve font".to_string(),
};
}
None => (),
};
}
Some(Self { font_path: ret })
}
#[cfg(target_os = "windows")]
pub fn find_fonts(font: String) -> Option<Self> {
let path = Path::new(
"C:\\Windows\\Fonts"
.to_owned()
.push_str(font.as_str())
.as_str(),
);
if path.exits() && path.is_dir() == false {
return Some(Self { font_path: path });
} else {
return None;
}
}
pub fn get(&self) -> String {
return self.font_path.clone();
}
}
#[derive(Clone)]
pub struct Image {
pub(crate) image: Img,
position: (f32, f32),
rotation: f32,
}
impl Image {
pub fn from_file(path: &str, position: (f32, f32)) -> Result<Self, String> {
let img = match Img::from_file(path) {
Some(i) => i,
None => return Err("Failed to load image from file".to_string()),
};
Ok(Self {
image: img,
position,
rotation: 0f32,
})
}
pub fn from_image(img: &Image) -> Option<Self> {
Some(Self {
image: img.image.clone(),
position: img.position.clone(),
rotation: img.rotation.clone(),
})
}
}
impl Image {
pub fn save(&self, path: &str) -> Result<(), String> {
match &self.image.save_to_file(path) {
true => Ok(()),
false => Err("Failed to save image".to_string()),
}
}
pub fn get_size(&self) -> Option<(u32, u32)> {
let res = &self.image.size();
Some((res.x, res.y))
}
pub fn get_pixel(&self, x: u32, y: u32) -> Option<Color> {
let res = &self.image.pixel_at(x, y);
match Color::from_sfml_color(res.clone()) {
Some(c) => return Some(c),
None => return None,
}
}
pub fn put_pixel(&mut self, x: u32, y: u32, color: Color) -> Result<(), String> {
let size = self.get_size().unwrap();
if x > size.0 {
return Err("X value out of range, this causes undefined behavior".to_string());
};
if y > size.1 {
return Err("Y value out of range, this causes undefined behavior".to_string());
} else {
self.image.set_pixel(x, y, color.c);
Ok(())
}
}
pub fn pixels_memory(&self) -> Option<&[u8]> {
Some(self.image.pixel_data())
}
pub fn set_position(&mut self, pos: (f32, f32)) -> Result<(), String> {
self.position = pos;
Ok(())
}
pub fn get_position(&self) -> Option<(f32, f32)> {
let pos = self.position;
Some(pos)
}
pub fn set_rotation(&mut self, angle: f32) -> Result<(), String> {
self.rotation = angle;
Ok(())
}
}