canrust 1.3.3

A Rust library for drawing shapes onto a canvas
//! Utilities for font handling and image processing
//! Contains structs FontHandler and Image.

use crate::canvas::Color;
use fontconfig::Fontconfig;
use sfml::graphics::Image as Img;
use std::path::Path;

#[derive(Debug, Clone)]
/// Struct responsible for font loading and handling .
pub struct FontHandler {
    font_path: String,
}

impl FontHandler {
    /// Use your own specific font file. Pass it's path as a String
    /// Supported formats can be found in SFML's documentation:
    /// [SFML DOCUMENTATION](https://docs.rs/sfml/0.15.1/sfml/graphics/struct.Font.html#method.from_file)
    /// ```no_run
    ///
    /// let handler = FontHandler::custom("~/myfont.ttf").expect("Unable to construct object!");
    ///
    /// ```
    pub fn custom(font_path: String) -> Option<Self> {
        let path = Path::new(&font_path);
        if path.is_dir() || path.exists() {
            path.to_str()?;
            return Some(Self {
                font_path: path.to_str().unwrap().to_string(),
            });
        } else {
            return None;
        }
    }

    /// Tries to match the given String with `fontconfig` and returns its path.
    /// ```no_run
    ///
    /// let handler = FontHandler::find_fonts("Source Code Pro").expect("Unable to construct object!");
    ///
    /// ```
    #[cfg(target_os = "linux")]
    pub fn find_fonts(f: String) -> Option<Self> {
        let fc = Fontconfig::new()?;
        let found = fc.find(&f, None)?;
        Some(Self {
            font_path: String::from(found.path.to_str()?),
        })
    }
    /// Not tested!
    /// Looks for the font file in the C:\\Windows\\Fonts\\
    /// ```no_run
    ///
    /// let fonthlander = FontHandler::find_fonts("Arial.ttf").expect("Font not found!");
    ///
    /// ```
    #[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;
        }
    }

    /// Returns font path field of the struct.
    /// Mainly used for debugging.
    pub fn get(&self) -> String {
        return self.font_path.clone();
    }
}

// Image
#[derive(Clone)]
/// Struct representing an image which can be projected onto a Canvas.
pub struct Image {
    pub(crate) image: Img,
    position: (f32, f32),
    rotation: f32,
}

impl Image {
    /// Load a new image from file.
    pub fn from_file(path: &str, position: (f32, f32)) -> Result<Self, Error> {
        let img = Img::from_file(path).ok_or(Error::GeneralError(String::from(
            "Unable to open file".to_string(),
        )))?;

        Ok(Self {
            image: img,
            position,
            rotation: 0f32,
        })
    }

    /// Clones an existing image from reference
    pub fn from_image(img: &Image) -> Self {
        Self {
            image: img.image.clone(),
            position: img.position.clone(),
            rotation: img.rotation.clone(),
        }
    }
}

impl Image {
    /// Saves Image to file
    pub fn save(&self, path: &str) -> bool {
        self.image.save_to_file(path)
    }

    /// Returns size of the Image
    pub fn get_size(&self) -> (u32, u32) {
        let res = &self.image.size();

        (res.x, res.y)
    }

    /// Returns color of a pixel at give coordinates
    pub fn get_pixel(&self, x: u32, y: u32) -> Color {
        let res = &self.image.pixel_at(x, y);

        Color::from_sfml_color(res.clone())
    }

    /// Gives a pixel at given coordinates a color.
    /// Returns and Error if the coordinates are too large.
    pub fn put_pixel(&mut self, x: u32, y: u32, color: Color) {
        self.image.set_pixel(x, y, color.c);
    }

    /// Returns Images memory buffer
    /// Can be used to for manipulation through crates like image
    pub fn pixels_memory(&self) -> &[u8] {
        self.image.pixel_data()
    }

    /// Sets objects position on the Canvas
    pub fn set_position(&mut self, pos: (f32, f32)) {
        self.position = pos;
    }

    /// Returns objects position on the Canvas
    pub fn get_position(&self) -> (f32, f32) {
        let pos = self.position;

        pos
    }

    /// Sets the angle at which the image will be displayed on Canvas
    pub fn set_rotation(&mut self, angle: f32) {
        self.rotation = angle;
    }
}

/// Crate error type
#[derive(Debug)]
pub enum Error {
    IoError(std::io::Error),
    FfiNullError(std::ffi::NulError),
    IoErrorKind(std::io::ErrorKind),
    GeneralError(String),
    NoneError(std::option::NoneError),
}

impl From<std::io::Error> for Error {
    fn from(error: std::io::Error) -> Self {
        Error::IoError(error)
    }
}

impl From<std::ffi::NulError> for Error {
    fn from(error: std::ffi::NulError) -> Self {
        Error::FfiNullError(error)
    }
}

impl From<std::io::ErrorKind> for Error {
    fn from(error: std::io::ErrorKind) -> Self {
        Self::IoErrorKind(error)
    }
}

impl From<std::option::NoneError> for Error {
    fn from(error: std::option::NoneError) -> Self {
        Self::NoneError(error)
    }
}

pub enum Wrapper<T> {
    I32(i32),
    U32(u32),
    WrapString(String),
    F32(f32),
    Custom(T),
}