|
|
- use std::rc::Rc;
- use std::error::Error;
- use std::collections::HashMap;
-
- use ::rasterizer::Font;
- use ::{FontAtlas, Scale};
- use ::texture::{Buffer2d, Bitmap};
-
- #[derive(PartialEq, Eq, Hash)]
- struct FaceKey {
- name: String,
- scale: Scale,
- }
-
- pub struct CachedFaceData<B> where B: Buffer2d {
- buffer: B,
- atlas: FontAtlas,
- line_height: f32,
- }
-
- #[derive(Debug)]
- pub enum CacheError {
- NoSuchFont(String)
- }
-
- pub struct Cache<'a, B> where B: Buffer2d {
- fonts: HashMap<String, Font<'a>>,
- faces: HashMap<FaceKey, CachedFaceData<B>>,
- upload_queue: Vec<FaceKey>,
- }
-
- impl<'a, B> Cache<'a, B> where B: Buffer2d {
- pub fn new() -> Cache<'a, B> {
- Cache {
- fonts: HashMap::new(),
- faces: HashMap::new(),
- upload_queue: Vec::new(),
- }
- }
-
- pub fn add_font<S>(&mut self, name: S, font: Font<'a>) where S: Into<String> {
- self.fonts.insert(name.into(), font);
- }
-
- pub fn build_face<I, F>(&mut self, name: &str, scale: f32,
- chars: I, buffer_transform: F) -> Result<(), CacheError>
- where I: Iterator<Item=char>,
- F: Fn(Bitmap<u8>) -> Result<B, CacheError>
- {
- let key = FaceKey {name: String::from(name), scale: Scale(scale)};
- if self.faces.contains_key(&key) {
- return Ok(());
- }
-
- match self.fonts.get(name) {
- Some(font) => {
- let face_data = CachedFaceData::new(font, scale, chars, buffer_transform)?;
- self.faces.insert(key, face_data);
-
- Ok(())
- },
- None => Err(CacheError::NoSuchFont(name.into())),
- }
- }
- }
-
- impl<B> CachedFaceData<B> where B: Buffer2d {
- pub fn new<I, F>(font: &Font, scale: f32, chars: I, buffer_transform: F)
- -> Result<CachedFaceData<B>, CacheError>
- where I: Iterator<Item=char>,
- F: Fn(Bitmap<u8>) -> Result<B, CacheError>
- {
- let (atlas, bitmap, line_height): (FontAtlas, Bitmap<u8>, f32) = font.make_atlas(chars, scale, 1, 256, 256);
-
- let bitmap = buffer_transform(bitmap)?;
-
- Ok(CachedFaceData {
- buffer: bitmap,
- atlas: atlas,
- line_height: line_height,
- })
- }
- }
|