Share font atlas
This commit is contained in:
parent
2fc191eed4
commit
1b8a45a514
7 changed files with 31 additions and 35 deletions
|
@ -58,10 +58,6 @@ impl Emigui {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn texture(&self) -> (u16, u16, &[u8]) {
|
||||
self.painter.texture()
|
||||
}
|
||||
|
||||
pub fn new_frame(&mut self, new_input: RawInput) {
|
||||
let gui_input = GuiInput::from_last_and_new(&self.last_input, &new_input);
|
||||
self.last_input = new_input;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use rusttype::{point, Scale};
|
||||
|
||||
use crate::{
|
||||
|
@ -58,11 +60,11 @@ pub struct Font {
|
|||
scale: usize,
|
||||
/// NUM_CHARS big
|
||||
glyph_infos: Vec<GlyphInfo>,
|
||||
atlas: TextureAtlas, // TODO: Arc<Mutex<TextureAtlas>>
|
||||
atlas: Arc<Mutex<TextureAtlas>>,
|
||||
}
|
||||
|
||||
impl Font {
|
||||
pub fn new(scale: usize) -> Font {
|
||||
pub fn new(scale: usize, atlas: Arc<Mutex<TextureAtlas>>) -> Font {
|
||||
// TODO: figure out a way to make the wasm smaller despite including a font.
|
||||
// let font_data = include_bytes!("../fonts/ProggyClean.ttf"); // Use 13 for this. NOTHING ELSE.
|
||||
// let font_data = include_bytes!("../fonts/DejaVuSans.ttf");
|
||||
|
@ -88,13 +90,8 @@ impl Font {
|
|||
})
|
||||
.collect();
|
||||
|
||||
let mut atlas = TextureAtlas::new(128, 8); // TODO: better default?
|
||||
|
||||
// Make one white pixel for use for various stuff:
|
||||
let pos = atlas.allocate((1, 1));
|
||||
atlas[pos] = 255;
|
||||
|
||||
let mut glyph_infos = vec![];
|
||||
let mut atlas_lock = atlas.lock().unwrap();
|
||||
|
||||
for glyph in glyphs {
|
||||
if let Some(bb) = glyph.pixel_bounding_box() {
|
||||
|
@ -103,13 +100,13 @@ impl Font {
|
|||
assert!(glyph_width >= 1);
|
||||
assert!(glyph_height >= 1);
|
||||
|
||||
let glyph_pos = atlas.allocate((glyph_width, glyph_height));
|
||||
let glyph_pos = atlas_lock.allocate((glyph_width, glyph_height));
|
||||
|
||||
glyph.draw(|x, y, v| {
|
||||
if v > 0.0 {
|
||||
let px = glyph_pos.0 + x as usize;
|
||||
let py = glyph_pos.1 + y as usize;
|
||||
atlas[(px, py)] = (v * 255.0).round() as u8;
|
||||
atlas_lock[(px, py)] = (v * 255.0).round() as u8;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -136,6 +133,8 @@ impl Font {
|
|||
}
|
||||
}
|
||||
|
||||
drop(atlas_lock);
|
||||
|
||||
Font {
|
||||
font,
|
||||
scale,
|
||||
|
@ -152,10 +151,6 @@ impl Font {
|
|||
(FIRST_ASCII..=LAST_ASCII).map(|c| c as u8 as char)
|
||||
}
|
||||
|
||||
pub fn texture(&self) -> (u16, u16, &[u8]) {
|
||||
self.atlas.texture()
|
||||
}
|
||||
|
||||
pub fn uv_rect(&self, c: char) -> Option<UvRect> {
|
||||
let c = c as usize;
|
||||
if FIRST_ASCII <= c && c <= LAST_ASCII {
|
||||
|
@ -280,6 +275,8 @@ impl Font {
|
|||
}
|
||||
|
||||
pub fn debug_print_all_chars(&self) {
|
||||
let atlas_lock = self.atlas.lock().unwrap();
|
||||
|
||||
let max_width = 160;
|
||||
let scale = Scale::uniform(self.scale as f32);
|
||||
let mut pixel_rows = vec![vec![0; max_width]; self.scale];
|
||||
|
@ -302,7 +299,7 @@ impl Font {
|
|||
if let Some(uv) = glyph.uv {
|
||||
for x in uv.min.0..=uv.max.0 {
|
||||
for y in uv.min.1..=uv.max.1 {
|
||||
let pixel = self.atlas[(x as usize, y as usize)];
|
||||
let pixel = atlas_lock[(x as usize, y as usize)];
|
||||
let rx = uv.offset.0 + x as i16 - uv.min.0 as i16;
|
||||
let ry = uv.offset.1 + y as i16 - uv.min.1 as i16;
|
||||
let px = (cursor_x + rx as f32).round();
|
||||
|
|
|
@ -23,5 +23,6 @@ pub use crate::{
|
|||
layout::Region,
|
||||
painter::{Frame, Painter, Vertex},
|
||||
style::Style,
|
||||
texture_atlas::TextureAtlas,
|
||||
types::RawInput,
|
||||
};
|
||||
|
|
|
@ -201,11 +201,6 @@ impl Painter {
|
|||
Painter { font }
|
||||
}
|
||||
|
||||
/// 8-bit row-major font atlas texture, (width, height, pixels).
|
||||
pub fn texture(&self) -> (u16, u16, &[u8]) {
|
||||
self.font.texture()
|
||||
}
|
||||
|
||||
pub fn paint(&self, commands: &[PaintCmd]) -> Frame {
|
||||
let mut path_points = Vec::new();
|
||||
let mut path_normals = Vec::new();
|
||||
|
|
|
@ -28,12 +28,8 @@ impl TextureAtlas {
|
|||
self.height
|
||||
}
|
||||
|
||||
pub fn pixels(&self) -> &[u8] {
|
||||
&self.pixels
|
||||
}
|
||||
|
||||
pub fn texture(&self) -> (u16, u16, &[u8]) {
|
||||
(self.width() as u16, self.height() as u16, self.pixels())
|
||||
pub fn into_texture(self) -> (u16, u16, Vec<u8>) {
|
||||
(self.width as u16, self.height as u16, self.pixels)
|
||||
}
|
||||
|
||||
/// Returns the coordinates of where the rect ended up.
|
||||
|
|
|
@ -5,9 +5,9 @@ extern crate wasm_bindgen;
|
|||
|
||||
extern crate emigui;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use emigui::{widgets::label, Emigui, Font, RawInput};
|
||||
use emigui::{widgets::label, Emigui, Font, RawInput, TextureAtlas};
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
|
@ -32,9 +32,20 @@ pub struct State {
|
|||
|
||||
impl State {
|
||||
fn new(canvas_id: &str) -> Result<State, JsValue> {
|
||||
let font = Arc::new(Font::new(20));
|
||||
let mut atlas = TextureAtlas::new(128, 8); // TODO: better default?
|
||||
|
||||
// Make one white pixel for use for various stuff:
|
||||
let pos = atlas.allocate((1, 1));
|
||||
atlas[pos] = 255;
|
||||
|
||||
let atlas = Arc::new(Mutex::new(atlas));
|
||||
|
||||
let font = Arc::new(Font::new(20, atlas.clone()));
|
||||
|
||||
let texture = atlas.lock().unwrap().clone().into_texture();
|
||||
|
||||
let emigui = Emigui::new(font);
|
||||
let webgl_painter = webgl::Painter::new(canvas_id, emigui.texture())?;
|
||||
let webgl_painter = webgl::Painter::new(canvas_id, texture)?;
|
||||
Ok(State {
|
||||
app: Default::default(),
|
||||
emigui,
|
||||
|
|
|
@ -34,7 +34,7 @@ impl Painter {
|
|||
|
||||
pub fn new(
|
||||
canvas_id: &str,
|
||||
(tex_width, tex_height, pixels): (u16, u16, &[u8]),
|
||||
(tex_width, tex_height, pixels): (u16, u16, Vec<u8>),
|
||||
) -> Result<Painter, JsValue> {
|
||||
let document = web_sys::window().unwrap().document().unwrap();
|
||||
let canvas = document.get_element_by_id(canvas_id).unwrap();
|
||||
|
|
Loading…
Reference in a new issue