logo-generator/src/text.rs

74 lines
1.8 KiB
Rust

use std::sync::Arc;
use cairo::{
freetype::{Face, Library},
Context,
};
use rust_embed::RustEmbed;
use tokio::sync::Mutex;
#[derive(RustEmbed)]
#[folder = "fonts"]
struct FontFiles;
struct InternalFonts {
light: Face,
regular: Face,
}
unsafe impl Send for InternalFonts {}
#[derive(Clone)]
pub struct EmbeddedFonts {
fonts: Arc<Mutex<InternalFonts>>,
}
impl EmbeddedFonts {
fn load_face(lib: &Library, name: &str) -> Result<Face, cairo::freetype::Error> {
let font_file = FontFiles::get(name).unwrap();
let font_data = Vec::from(font_file.data);
lib.new_memory_face(font_data, 0)
}
pub fn load() -> EmbeddedFonts {
let lib = Library::init().unwrap();
let font_regular = Self::load_face(&lib, "Nunito-Regular.ttf").unwrap();
let font_light = Self::load_face(&lib, "Nunito-Light.ttf").unwrap();
let fonts = InternalFonts {
regular: font_regular,
light: font_light,
};
EmbeddedFonts {
fonts: Arc::new(Mutex::new(fonts)),
}
}
pub async fn get(&self) -> (Face, Face) {
let fonts = self.fonts.lock().await;
(fonts.regular.clone(), fonts.light.clone())
}
}
pub struct DrawableText {
pub position: (f64, f64),
pub size: f64,
pub spacing: f64,
pub text: &'static str,
}
impl DrawableText {
pub fn draw(&self, context: &Context) {
context.new_path();
context.set_font_size(self.size);
context.line_to(self.position.0, self.position.1);
for char in self.text.chars() {
context.text_path(&String::from(char));
let (x, y) = context.current_point().unwrap();
context.line_to(x + self.spacing, y);
}
context.close_path();
context.fill().unwrap();
}
}