egui/emigui/src/fonts.rs

100 lines
2.7 KiB
Rust
Raw Normal View History

2019-01-12 23:55:56 +00:00
use std::{
2019-01-17 17:03:39 +00:00
collections::{hash_map::DefaultHasher, BTreeMap},
hash::{Hash, Hasher},
2019-01-12 23:55:56 +00:00
sync::{Arc, Mutex},
};
2019-01-16 23:09:12 +00:00
use crate::{
font::Font,
texture_atlas::{Texture, TextureAtlas},
};
2019-01-12 23:55:56 +00:00
/// TODO: rename
2019-01-17 17:03:39 +00:00
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
2019-01-12 23:55:56 +00:00
pub enum TextStyle {
Body,
Button,
Heading,
// Monospace,
}
2019-01-17 17:03:39 +00:00
pub type FontSizes = BTreeMap<TextStyle, f32>;
2019-01-12 23:55:56 +00:00
pub struct Fonts {
2019-01-19 16:10:28 +00:00
pixels_per_point: f32,
2019-01-17 17:03:39 +00:00
sizes: FontSizes,
2019-01-12 23:55:56 +00:00
fonts: BTreeMap<TextStyle, Font>,
2019-01-16 23:09:12 +00:00
texture: Texture,
2019-01-12 23:55:56 +00:00
}
impl Fonts {
2019-01-19 16:10:28 +00:00
pub fn new(pixels_per_point: f32) -> Fonts {
2019-01-17 17:03:39 +00:00
let mut sizes = FontSizes::new();
2019-01-17 23:34:01 +00:00
sizes.insert(TextStyle::Body, 18.0);
sizes.insert(TextStyle::Button, 22.0);
2019-01-19 16:09:00 +00:00
sizes.insert(TextStyle::Heading, 28.0);
2019-01-19 16:10:28 +00:00
Fonts::from_sizes(sizes, pixels_per_point)
2019-01-17 17:03:39 +00:00
}
2019-01-19 16:10:28 +00:00
pub fn from_sizes(sizes: FontSizes, pixels_per_point: f32) -> Fonts {
2019-01-17 17:03:39 +00:00
let mut fonts = Fonts {
2019-01-19 16:10:28 +00:00
pixels_per_point,
2019-01-17 17:03:39 +00:00
sizes: Default::default(),
fonts: Default::default(),
texture: Default::default(),
};
fonts.set_sizes(sizes);
fonts
}
pub fn sizes(&self) -> &FontSizes {
&self.sizes
}
pub fn set_sizes(&mut self, sizes: FontSizes) {
if self.sizes == sizes {
return;
}
let mut atlas = TextureAtlas::new(512, 8); // TODO: better default?
2019-01-12 23:55:56 +00:00
// Make one white pixel for use for various stuff:
let pos = atlas.allocate((1, 1));
2019-01-16 23:09:12 +00:00
atlas.texture_mut()[pos] = 255;
2019-01-12 23:55:56 +00:00
let atlas = Arc::new(Mutex::new(atlas));
2019-01-17 17:03:39 +00:00
// TODO: figure out a way to make the wasm smaller despite including a font. Zip it?
2019-01-16 23:09:12 +00:00
// let typeface_data = include_bytes!("../fonts/ProggyClean.ttf"); // Use 13 for this. NOTHING ELSE.
// let typeface_data = include_bytes!("../fonts/DejaVuSans.ttf");
let typeface_data = include_bytes!("../fonts/Roboto-Regular.ttf");
2019-01-17 17:03:39 +00:00
self.sizes = sizes.clone();
self.fonts = sizes
.into_iter()
2019-01-19 16:10:28 +00:00
.map(|(text_style, size)| {
(
text_style,
Font::new(atlas.clone(), typeface_data, size, self.pixels_per_point),
)
})
2019-01-17 17:03:39 +00:00
.collect();
self.texture = atlas.lock().unwrap().texture().clone();
2019-01-12 23:55:56 +00:00
2019-01-17 17:03:39 +00:00
let mut hasher = DefaultHasher::new();
self.texture.pixels.hash(&mut hasher);
self.texture.id = hasher.finish();
2019-01-12 23:55:56 +00:00
}
2019-01-16 23:09:12 +00:00
pub fn texture(&self) -> &Texture {
&self.texture
2019-01-12 23:55:56 +00:00
}
}
impl std::ops::Index<TextStyle> for Fonts {
type Output = Font;
fn index(&self, text_style: TextStyle) -> &Font {
&self.fonts[&text_style]
}
}