Share font atlas

This commit is contained in:
Emil Ernerfeldt 2019-01-13 00:19:53 +01:00
parent 2fc191eed4
commit 1b8a45a514
7 changed files with 31 additions and 35 deletions

View file

@ -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;

View file

@ -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();

View file

@ -23,5 +23,6 @@ pub use crate::{
layout::Region,
painter::{Frame, Painter, Vertex},
style::Style,
texture_atlas::TextureAtlas,
types::RawInput,
};

View file

@ -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();

View file

@ -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.

View file

@ -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,

View file

@ -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();