sprite_cache.rs

 1use std::{collections::HashMap, sync::Arc};
 2
 3use crate::{
 4    fonts::{FontId, GlyphId},
 5    geometry::{rect::RectI, vector::Vector2I},
 6    FontCache,
 7};
 8use etagere::BucketedAtlasAllocator;
 9use metal::{MTLPixelFormat, TextureDescriptor};
10use ordered_float::OrderedFloat;
11
12#[derive(Hash, Eq, PartialEq)]
13struct GlyphDescriptor {
14    font_id: FontId,
15    font_size: OrderedFloat<f32>,
16    glyph_id: GlyphId,
17}
18
19pub struct SpriteCache {
20    font_cache: Arc<FontCache>,
21    device: metal::Device,
22    size: Vector2I,
23    atlasses: Vec<Atlas>,
24    glyphs: HashMap<GlyphDescriptor, (usize, RectI)>,
25}
26
27impl SpriteCache {
28    pub fn new(device: metal::Device, size: Vector2I) -> Self {
29        Self {
30            device,
31            size,
32            atlasses: vec![Atlas::new(&device, size)],
33            glyphs: Default::default(),
34        }
35    }
36
37    pub fn render_glyph(
38        &mut self,
39        font_id: FontId,
40        font_size: f32,
41        glyph_id: GlyphId,
42    ) -> (usize, RectI) {
43        self.glyphs
44            .entry(GlyphDescriptor {
45                font_id,
46                font_size: OrderedFloat(font_size),
47                glyph_id,
48            })
49            .or_insert_with(|| {
50                let rendered_glyph = self.font_cache.render_glyph(font_id, font_size, glyph_id);
51                // let atlas = self.atlasses.last_mut().unwrap();
52                todo!()
53            })
54            .clone()
55    }
56}
57
58struct Atlas {
59    allocator: BucketedAtlasAllocator,
60    texture: metal::Texture,
61}
62
63impl Atlas {
64    fn new(device: &metal::DeviceRef, size: Vector2I) -> Self {
65        let descriptor = TextureDescriptor::new();
66        descriptor.set_pixel_format(MTLPixelFormat::A8Unorm);
67        descriptor.set_width(size.x() as u64);
68        descriptor.set_height(size.y() as u64);
69
70        Self {
71            allocator: BucketedAtlasAllocator::new(etagere::Size::new(size.x(), size.y())),
72            texture: device.new_texture(&descriptor),
73        }
74    }
75}