mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-11-24 15:58:43 -06:00
font cache!
This commit is contained in:
parent
cc32082c21
commit
225cecf1fa
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -548,7 +548,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0793f5137567643cf65ea42043a538804ff0fbf288649e2141442b602d81f9bc"
|
checksum = "0793f5137567643cf65ea42043a538804ff0fbf288649e2141442b602d81f9bc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown 0.13.2",
|
"hashbrown 0.13.2",
|
||||||
"rayon",
|
|
||||||
"ttf-parser 0.15.2",
|
"ttf-parser 0.15.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -774,7 +773,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
|
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"rayon",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1048,7 +1046,6 @@ dependencies = [
|
||||||
"kubi-logging",
|
"kubi-logging",
|
||||||
"log",
|
"log",
|
||||||
"nohash-hasher",
|
"nohash-hasher",
|
||||||
"rayon",
|
|
||||||
"rect_packer",
|
"rect_packer",
|
||||||
"winit",
|
"winit",
|
||||||
]
|
]
|
||||||
|
|
|
@ -10,9 +10,8 @@ nohash-hasher = "0.2"
|
||||||
glam = "0.24"
|
glam = "0.24"
|
||||||
glium = { git = "https://github.com/glium/glium", rev = "968fc92378caf", optional = true }
|
glium = { git = "https://github.com/glium/glium", rev = "968fc92378caf", optional = true }
|
||||||
fontdue = "0.7"
|
fontdue = "0.7"
|
||||||
rect_packer = { version = "0.2.1", optional = true }
|
rect_packer = "0.2"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
rayon = { version = "1.8", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
kubi-logging = { path = "../kubi-logging" }
|
kubi-logging = { path = "../kubi-logging" }
|
||||||
|
@ -20,8 +19,8 @@ glium = { git = "https://github.com/glium/glium", rev = "968fc92378caf" }
|
||||||
winit = "0.29"
|
winit = "0.29"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["builtin_elements", "builtin_font", "backend_glium", "parallel"]
|
default = ["builtin_elements", "builtin_font", "backend_glium"]
|
||||||
backend_glium = ["dep:glium"]
|
backend_glium = ["dep:glium"]
|
||||||
builtin_font = []
|
builtin_font = []
|
||||||
builtin_elements = []
|
builtin_elements = []
|
||||||
parallel = ["dep:rayon", "fontdue/parallel"]
|
#parallel = ["dep:rayon", "fontdue/parallel"]
|
||||||
|
|
|
@ -43,7 +43,7 @@ impl KubiUi {
|
||||||
draw_commands: UiDrawCommands::default(),
|
draw_commands: UiDrawCommands::default(),
|
||||||
draw_plan: UiDrawPlan::default(),
|
draw_plan: UiDrawPlan::default(),
|
||||||
draw_plan_modified: false,
|
draw_plan_modified: false,
|
||||||
font_renderer: TextRenderer::new(),
|
font_renderer: TextRenderer::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,59 +1,87 @@
|
||||||
|
use std::sync::Arc;
|
||||||
use fontdue::{Font, Metrics};
|
use fontdue::{Font, Metrics};
|
||||||
|
use glam::{IVec2, UVec2, uvec2, ivec2};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use nohash_hasher::BuildNoHashHasher;
|
use rect_packer::DensePacker;
|
||||||
|
|
||||||
#[cfg(feature = "parallel")]
|
|
||||||
use rayon::prelude::*;
|
|
||||||
|
|
||||||
#[cfg(feature = "builtin_font")]
|
#[cfg(feature = "builtin_font")]
|
||||||
const BIN_FONT: &[u8] = include_bytes!("../assets/font/ProggyTiny.ttf");
|
const BIN_FONT: &[u8] = include_bytes!("../assets/font/ProggyTiny.ttf");
|
||||||
|
|
||||||
// pub struct Glyph {
|
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
// pub metrics: Metrics,
|
pub struct FontHandle(pub(crate) usize);
|
||||||
// pub data: Box<[u8]>
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub struct FontData {
|
#[derive(PartialEq, Eq, Hash)]
|
||||||
// font: Font,
|
struct GlyphCacheKey {
|
||||||
// cache: HashMap<(u8, char), Glyph, BuildNoHashHasher<u8>>
|
font_index: usize,
|
||||||
// }
|
character: char,
|
||||||
|
size: u8,
|
||||||
|
}
|
||||||
|
|
||||||
// impl FontData {
|
struct GlyphCacheEntry {
|
||||||
// pub fn new() -> Self {
|
pub data: Vec<u8>,
|
||||||
// FontData {
|
pub metrics: Metrics,
|
||||||
// font: Font::from_bytes(BIN_FONT, fontdue::FontSettings::default()).unwrap(),
|
pub texture_position: IVec2,
|
||||||
// cache: HashMap::default()
|
pub texture_size: UVec2,
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// fn prebake(&mut self, size: u8) {
|
|
||||||
// self.cache = (33..=126).par_bridge().map(|c| {
|
|
||||||
// let (metrics, data) = self.font.rasterize(
|
|
||||||
// char::from(c),
|
|
||||||
// c as f32,
|
|
||||||
// );
|
|
||||||
// Glyph { metrics, data: data.into_boxed_slice() }
|
|
||||||
// }).collect();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub struct TextRenderer {
|
pub struct TextRenderer {
|
||||||
font_stack: Vec<Font>,
|
fonts: Vec<Font>,
|
||||||
cache: ()
|
glyph_cache: HashMap<GlyphCacheKey, Arc<GlyphCacheEntry>>,
|
||||||
|
packer: DensePacker,
|
||||||
|
font_texture: Vec<u8>,
|
||||||
|
font_texture_size: UVec2,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextRenderer {
|
impl TextRenderer {
|
||||||
pub fn new() -> Self {
|
pub fn new(size: UVec2) -> Self {
|
||||||
let font = Font::from_bytes(BIN_FONT, fontdue::FontSettings::default()).unwrap();
|
let mut renderer = TextRenderer {
|
||||||
TextRenderer {
|
fonts: Vec::new(),
|
||||||
font_stack: vec![font],
|
glyph_cache: HashMap::new(),
|
||||||
cache: ()
|
packer: DensePacker::new(size.x as i32, size.y as i32),
|
||||||
|
font_texture: vec![0; (size.x * size.y) as usize],
|
||||||
|
font_texture_size: size,
|
||||||
|
};
|
||||||
|
#[cfg(feature = "builtin_font")]
|
||||||
|
{
|
||||||
|
let font = Font::from_bytes(BIN_FONT, fontdue::FontSettings::default()).unwrap();
|
||||||
|
renderer.add_font(font);
|
||||||
}
|
}
|
||||||
|
renderer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a (fontdue) font to the renderer.
|
||||||
|
pub fn add_font(&mut self, font: Font) -> FontHandle {
|
||||||
|
self.fonts.push(font);
|
||||||
|
FontHandle(self.fonts.len() - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Either looks up the glyph in the cache or renders it and adds it to the cache.
|
||||||
|
pub fn glyph(&mut self, font: FontHandle, character: char, size: u8) -> Arc<GlyphCacheEntry> {
|
||||||
|
let key = GlyphCacheKey {
|
||||||
|
font_index: font.0,
|
||||||
|
character,
|
||||||
|
size,
|
||||||
|
};
|
||||||
|
if let Some(entry) = self.glyph_cache.get(&key) {
|
||||||
|
return Arc::clone(entry);
|
||||||
|
}
|
||||||
|
let font = &self.fonts[key.font_index];
|
||||||
|
let (metrics, bitmap) = font.rasterize(character, size as f32);
|
||||||
|
let texture_position = self.packer.pack(metrics.width as i32, metrics.height as i32, false).unwrap();
|
||||||
|
let texture_size = uvec2(metrics.width as u32, metrics.height as u32);
|
||||||
|
let entry = Arc::new(GlyphCacheEntry {
|
||||||
|
data: bitmap,
|
||||||
|
metrics,
|
||||||
|
texture_position: ivec2(texture_position.x, texture_position.y),
|
||||||
|
texture_size,
|
||||||
|
});
|
||||||
|
self.glyph_cache.insert_unique_unchecked(key, Arc::clone(&entry));
|
||||||
|
entry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TextRenderer {
|
impl Default for TextRenderer {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new(uvec2(2048, 2048))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue