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) {
|
pub fn new_frame(&mut self, new_input: RawInput) {
|
||||||
let gui_input = GuiInput::from_last_and_new(&self.last_input, &new_input);
|
let gui_input = GuiInput::from_last_and_new(&self.last_input, &new_input);
|
||||||
self.last_input = new_input;
|
self.last_input = new_input;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use rusttype::{point, Scale};
|
use rusttype::{point, Scale};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -58,11 +60,11 @@ pub struct Font {
|
||||||
scale: usize,
|
scale: usize,
|
||||||
/// NUM_CHARS big
|
/// NUM_CHARS big
|
||||||
glyph_infos: Vec<GlyphInfo>,
|
glyph_infos: Vec<GlyphInfo>,
|
||||||
atlas: TextureAtlas, // TODO: Arc<Mutex<TextureAtlas>>
|
atlas: Arc<Mutex<TextureAtlas>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Font {
|
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.
|
// 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/ProggyClean.ttf"); // Use 13 for this. NOTHING ELSE.
|
||||||
// let font_data = include_bytes!("../fonts/DejaVuSans.ttf");
|
// let font_data = include_bytes!("../fonts/DejaVuSans.ttf");
|
||||||
|
@ -88,13 +90,8 @@ impl Font {
|
||||||
})
|
})
|
||||||
.collect();
|
.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 glyph_infos = vec![];
|
||||||
|
let mut atlas_lock = atlas.lock().unwrap();
|
||||||
|
|
||||||
for glyph in glyphs {
|
for glyph in glyphs {
|
||||||
if let Some(bb) = glyph.pixel_bounding_box() {
|
if let Some(bb) = glyph.pixel_bounding_box() {
|
||||||
|
@ -103,13 +100,13 @@ impl Font {
|
||||||
assert!(glyph_width >= 1);
|
assert!(glyph_width >= 1);
|
||||||
assert!(glyph_height >= 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| {
|
glyph.draw(|x, y, v| {
|
||||||
if v > 0.0 {
|
if v > 0.0 {
|
||||||
let px = glyph_pos.0 + x as usize;
|
let px = glyph_pos.0 + x as usize;
|
||||||
let py = glyph_pos.1 + y 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 {
|
||||||
font,
|
font,
|
||||||
scale,
|
scale,
|
||||||
|
@ -152,10 +151,6 @@ impl Font {
|
||||||
(FIRST_ASCII..=LAST_ASCII).map(|c| c as u8 as char)
|
(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> {
|
pub fn uv_rect(&self, c: char) -> Option<UvRect> {
|
||||||
let c = c as usize;
|
let c = c as usize;
|
||||||
if FIRST_ASCII <= c && c <= LAST_ASCII {
|
if FIRST_ASCII <= c && c <= LAST_ASCII {
|
||||||
|
@ -280,6 +275,8 @@ impl Font {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_print_all_chars(&self) {
|
pub fn debug_print_all_chars(&self) {
|
||||||
|
let atlas_lock = self.atlas.lock().unwrap();
|
||||||
|
|
||||||
let max_width = 160;
|
let max_width = 160;
|
||||||
let scale = Scale::uniform(self.scale as f32);
|
let scale = Scale::uniform(self.scale as f32);
|
||||||
let mut pixel_rows = vec![vec![0; max_width]; self.scale];
|
let mut pixel_rows = vec![vec![0; max_width]; self.scale];
|
||||||
|
@ -302,7 +299,7 @@ impl Font {
|
||||||
if let Some(uv) = glyph.uv {
|
if let Some(uv) = glyph.uv {
|
||||||
for x in uv.min.0..=uv.max.0 {
|
for x in uv.min.0..=uv.max.0 {
|
||||||
for y in uv.min.1..=uv.max.1 {
|
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 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 ry = uv.offset.1 + y as i16 - uv.min.1 as i16;
|
||||||
let px = (cursor_x + rx as f32).round();
|
let px = (cursor_x + rx as f32).round();
|
||||||
|
|
|
@ -23,5 +23,6 @@ pub use crate::{
|
||||||
layout::Region,
|
layout::Region,
|
||||||
painter::{Frame, Painter, Vertex},
|
painter::{Frame, Painter, Vertex},
|
||||||
style::Style,
|
style::Style,
|
||||||
|
texture_atlas::TextureAtlas,
|
||||||
types::RawInput,
|
types::RawInput,
|
||||||
};
|
};
|
||||||
|
|
|
@ -201,11 +201,6 @@ impl Painter {
|
||||||
Painter { font }
|
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 {
|
pub fn paint(&self, commands: &[PaintCmd]) -> Frame {
|
||||||
let mut path_points = Vec::new();
|
let mut path_points = Vec::new();
|
||||||
let mut path_normals = Vec::new();
|
let mut path_normals = Vec::new();
|
||||||
|
|
|
@ -28,12 +28,8 @@ impl TextureAtlas {
|
||||||
self.height
|
self.height
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pixels(&self) -> &[u8] {
|
pub fn into_texture(self) -> (u16, u16, Vec<u8>) {
|
||||||
&self.pixels
|
(self.width as u16, self.height as u16, self.pixels)
|
||||||
}
|
|
||||||
|
|
||||||
pub fn texture(&self) -> (u16, u16, &[u8]) {
|
|
||||||
(self.width() as u16, self.height() as u16, self.pixels())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the coordinates of where the rect ended up.
|
/// Returns the coordinates of where the rect ended up.
|
||||||
|
|
|
@ -5,9 +5,9 @@ extern crate wasm_bindgen;
|
||||||
|
|
||||||
extern crate emigui;
|
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::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
@ -32,9 +32,20 @@ pub struct State {
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
fn new(canvas_id: &str) -> Result<State, JsValue> {
|
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 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 {
|
Ok(State {
|
||||||
app: Default::default(),
|
app: Default::default(),
|
||||||
emigui,
|
emigui,
|
||||||
|
|
|
@ -34,7 +34,7 @@ impl Painter {
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
canvas_id: &str,
|
canvas_id: &str,
|
||||||
(tex_width, tex_height, pixels): (u16, u16, &[u8]),
|
(tex_width, tex_height, pixels): (u16, u16, Vec<u8>),
|
||||||
) -> Result<Painter, JsValue> {
|
) -> Result<Painter, JsValue> {
|
||||||
let document = web_sys::window().unwrap().document().unwrap();
|
let document = web_sys::window().unwrap().document().unwrap();
|
||||||
let canvas = document.get_element_by_id(canvas_id).unwrap();
|
let canvas = document.get_element_by_id(canvas_id).unwrap();
|
||||||
|
|
Loading…
Reference in a new issue