thanks, jk
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
2.2 KiB

  1. use std::rc::Rc;
  2. use std::error::Error;
  3. use std::collections::HashMap;
  4. use ::rasterizer::Font;
  5. use ::{FontAtlas, Scale};
  6. use ::texture::{Buffer2d, Bitmap};
  7. #[derive(PartialEq, Eq, Hash)]
  8. struct FaceKey {
  9. name: String,
  10. scale: Scale,
  11. }
  12. pub struct CachedFaceData<B> where B: Buffer2d {
  13. buffer: B,
  14. atlas: FontAtlas,
  15. line_height: f32,
  16. }
  17. #[derive(Debug)]
  18. pub enum CacheError {
  19. NoSuchFont(String)
  20. }
  21. pub struct Cache<'a, B> where B: Buffer2d {
  22. fonts: HashMap<String, Font<'a>>,
  23. faces: HashMap<FaceKey, CachedFaceData<B>>,
  24. upload_queue: Vec<FaceKey>,
  25. }
  26. impl<'a, B> Cache<'a, B> where B: Buffer2d {
  27. pub fn new() -> Cache<'a, B> {
  28. Cache {
  29. fonts: HashMap::new(),
  30. faces: HashMap::new(),
  31. upload_queue: Vec::new(),
  32. }
  33. }
  34. pub fn add_font<S>(&mut self, name: S, font: Font<'a>) where S: Into<String> {
  35. self.fonts.insert(name.into(), font);
  36. }
  37. pub fn build_face<I, F>(&mut self, name: &str, scale: f32,
  38. chars: I, buffer_transform: F) -> Result<(), CacheError>
  39. where I: Iterator<Item=char>,
  40. F: Fn(Bitmap<u8>) -> Result<B, CacheError>
  41. {
  42. let key = FaceKey {name: String::from(name), scale: Scale(scale)};
  43. if self.faces.contains_key(&key) {
  44. return Ok(());
  45. }
  46. match self.fonts.get(name) {
  47. Some(font) => {
  48. let face_data = CachedFaceData::new(font, scale, chars, buffer_transform)?;
  49. self.faces.insert(key, face_data);
  50. Ok(())
  51. },
  52. None => Err(CacheError::NoSuchFont(name.into())),
  53. }
  54. }
  55. }
  56. impl<B> CachedFaceData<B> where B: Buffer2d {
  57. pub fn new<I, F>(font: &Font, scale: f32, chars: I, buffer_transform: F)
  58. -> Result<CachedFaceData<B>, CacheError>
  59. where I: Iterator<Item=char>,
  60. F: Fn(Bitmap<u8>) -> Result<B, CacheError>
  61. {
  62. let (atlas, bitmap, line_height): (FontAtlas, Bitmap<u8>, f32) = font.make_atlas(chars, scale, 1, 256, 256);
  63. let bitmap = buffer_transform(bitmap)?;
  64. Ok(CachedFaceData {
  65. buffer: bitmap,
  66. atlas: atlas,
  67. line_height: line_height,
  68. })
  69. }
  70. }