Non-monospaced fonts
This commit is contained in:
parent
ad352e4a1e
commit
fafc802ffd
11 changed files with 167 additions and 101 deletions
|
@ -28,3 +28,4 @@ Supports MARKDEEP. A place for you ideas. Stored on your computer (local storage
|
||||||
# Credits / Licenses
|
# Credits / Licenses
|
||||||
|
|
||||||
ProggyClean.ttf, Copyright (c) 2004, 2005 Tristan Grimmer. MIT License. http://www.proggyfonts.net/
|
ProggyClean.ttf, Copyright (c) 2004, 2005 Tristan Grimmer. MIT License. http://www.proggyfonts.net/
|
||||||
|
Roboto-Regular.ttf: Apache License, Version 2.0
|
||||||
|
|
Binary file not shown.
BIN
emgui/fonts/DejaVuSans.ttf
Normal file
BIN
emgui/fonts/DejaVuSans.ttf
Normal file
Binary file not shown.
|
@ -1,4 +1,4 @@
|
||||||
use crate::{layout, style, types::*};
|
use crate::{font::Font, layout, style, types::*};
|
||||||
|
|
||||||
/// Encapsulates input, layout and painting for ease of use.
|
/// Encapsulates input, layout and painting for ease of use.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -9,10 +9,10 @@ pub struct Emgui {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Emgui {
|
impl Emgui {
|
||||||
pub fn new() -> Emgui {
|
pub fn new(font: Font) -> Emgui {
|
||||||
Emgui {
|
Emgui {
|
||||||
last_input: Default::default(),
|
last_input: Default::default(),
|
||||||
layout: layout::Layout::new(),
|
layout: layout::Layout::new(font),
|
||||||
style: Default::default(),
|
style: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,13 @@
|
||||||
use rusttype::{point, Scale};
|
use rusttype::{point, Scale};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub struct GlyphInfo {
|
pub struct UvRect {
|
||||||
/// X offset for nice rendering
|
/// X/Y offset for nice rendering
|
||||||
pub offset_x: u16,
|
pub offset_x: i16,
|
||||||
|
|
||||||
/// Y offset for nice rendering
|
/// Y offset for nice rendering
|
||||||
pub offset_y: u16,
|
pub offset_y: i16,
|
||||||
|
|
||||||
// Texture coordinates:
|
|
||||||
pub min_x: u16,
|
pub min_x: u16,
|
||||||
pub min_y: u16,
|
pub min_y: u16,
|
||||||
|
|
||||||
|
@ -21,19 +20,29 @@ pub struct GlyphInfo {
|
||||||
pub max_y: u16,
|
pub max_y: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Printable ascii characters [33, 126], which excludes 32 (space) and 127 (DEL)
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
const NUM_CHARS: usize = 94;
|
pub struct GlyphInfo {
|
||||||
const FIRST_ASCII: usize = 33;
|
id: rusttype::GlyphId,
|
||||||
/// Inclusive
|
|
||||||
|
pub advance_width: f32,
|
||||||
|
|
||||||
|
/// Texture coordinates. None for space.
|
||||||
|
pub uv: Option<UvRect>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Printable ASCII characters [32, 126], which excludes control codes.
|
||||||
|
const FIRST_ASCII: usize = 32; // 32 == space
|
||||||
const LAST_ASCII: usize = 126;
|
const LAST_ASCII: usize = 126;
|
||||||
|
const NUM_CHARS: usize = LAST_ASCII - FIRST_ASCII + 1;
|
||||||
|
|
||||||
// TODO: break out texture atlas into separate struct, and fill it dynamically, potentially from multiple fonts.
|
// TODO: break out texture atlas into separate struct, and fill it dynamically, potentially from multiple fonts.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Font {
|
pub struct Font {
|
||||||
|
font: rusttype::Font<'static>,
|
||||||
/// Maximum character height
|
/// Maximum character height
|
||||||
scale: usize,
|
scale: usize,
|
||||||
/// NUM_CHARS big
|
/// NUM_CHARS big
|
||||||
char_rects: Vec<GlyphInfo>,
|
glyph_infos: Vec<GlyphInfo>,
|
||||||
atlas_width: usize,
|
atlas_width: usize,
|
||||||
atlas_height: usize,
|
atlas_height: usize,
|
||||||
atlas: Vec<u8>,
|
atlas: Vec<u8>,
|
||||||
|
@ -41,7 +50,8 @@ pub struct Font {
|
||||||
|
|
||||||
impl Font {
|
impl Font {
|
||||||
pub fn new(scale: usize) -> Font {
|
pub fn new(scale: usize) -> Font {
|
||||||
let font_data = include_bytes!("../fonts/ProggyClean.ttf");
|
// let font_data = include_bytes!("../fonts/ProggyClean.ttf"); // Use 13 for this. NOTHING ELSE.
|
||||||
|
let font_data = include_bytes!("../fonts/DejaVuSans.ttf"); // 20 works nicely for this.
|
||||||
let font = rusttype::Font::from_bytes(font_data as &[u8]).expect("Error constructing Font");
|
let font = rusttype::Font::from_bytes(font_data as &[u8]).expect("Error constructing Font");
|
||||||
|
|
||||||
// println!(
|
// println!(
|
||||||
|
@ -76,12 +86,10 @@ impl Font {
|
||||||
let mut cursor_y = 0;
|
let mut cursor_y = 0;
|
||||||
let mut row_height = 1;
|
let mut row_height = 1;
|
||||||
|
|
||||||
let mut char_rects = vec![];
|
let mut glyph_infos = vec![];
|
||||||
|
|
||||||
for glyph in glyphs {
|
for glyph in glyphs {
|
||||||
let bb = glyph
|
if let Some(bb) = glyph.pixel_bounding_box() {
|
||||||
.pixel_bounding_box()
|
|
||||||
.expect("Failed to get pixel bounding box");
|
|
||||||
let glyph_width = bb.width() as usize;
|
let glyph_width = bb.width() as usize;
|
||||||
let glyph_height = bb.height() as usize;
|
let glyph_height = bb.height() as usize;
|
||||||
assert!(glyph_width >= 1);
|
assert!(glyph_width >= 1);
|
||||||
|
@ -112,30 +120,45 @@ impl Font {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let offset_y = scale as i32 + bb.min.y - 3; // TODO: use font.v_metrics
|
let offset_y = scale as i16 + bb.min.y as i16 - 3; // TODO: use font.v_metrics
|
||||||
assert!(0 <= bb.min.x);
|
glyph_infos.push(GlyphInfo {
|
||||||
assert!(0 <= offset_y && offset_y < scale as i32);
|
id: glyph.id(),
|
||||||
char_rects.push(GlyphInfo {
|
advance_width: glyph.unpositioned().h_metrics().advance_width,
|
||||||
offset_x: bb.min.x as u16,
|
uv: Some(UvRect {
|
||||||
offset_y: offset_y as u16,
|
offset_x: bb.min.x as i16,
|
||||||
|
offset_y: offset_y as i16,
|
||||||
min_x: cursor_x as u16,
|
min_x: cursor_x as u16,
|
||||||
min_y: cursor_y as u16,
|
min_y: cursor_y as u16,
|
||||||
max_x: (cursor_x + glyph_width - 1) as u16,
|
max_x: (cursor_x + glyph_width - 1) as u16,
|
||||||
max_y: (cursor_y + glyph_height - 1) as u16,
|
max_y: (cursor_y + glyph_height - 1) as u16,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
cursor_x += glyph_width;
|
cursor_x += glyph_width;
|
||||||
|
} else {
|
||||||
|
// No bounding box. Maybe a space?
|
||||||
|
glyph_infos.push(GlyphInfo {
|
||||||
|
id: glyph.id(),
|
||||||
|
advance_width: glyph.unpositioned().h_metrics().advance_width,
|
||||||
|
uv: None,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Font {
|
Font {
|
||||||
|
font,
|
||||||
scale,
|
scale,
|
||||||
char_rects,
|
glyph_infos,
|
||||||
atlas_width,
|
atlas_width,
|
||||||
atlas_height,
|
atlas_height,
|
||||||
atlas,
|
atlas,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn line_spacing(&self) -> f32 {
|
||||||
|
self.scale as f32
|
||||||
|
}
|
||||||
|
|
||||||
pub fn supported_characters() -> impl Iterator<Item = char> {
|
pub fn supported_characters() -> impl Iterator<Item = char> {
|
||||||
(FIRST_ASCII..=LAST_ASCII).map(|c| c as u8 as char)
|
(FIRST_ASCII..=LAST_ASCII).map(|c| c as u8 as char)
|
||||||
}
|
}
|
||||||
|
@ -156,10 +179,19 @@ impl Font {
|
||||||
self.atlas[y * self.atlas_width + x]
|
self.atlas[y * self.atlas_width + x]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn glyph_info(&self, c: char) -> Option<GlyphInfo> {
|
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 {
|
||||||
Some(self.char_rects[c - FIRST_ASCII])
|
self.glyph_infos[c - FIRST_ASCII].uv
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn glyph_info(&self, c: char) -> Option<GlyphInfo> {
|
||||||
|
let c = c as usize;
|
||||||
|
if FIRST_ASCII <= c && c <= LAST_ASCII {
|
||||||
|
Some(self.glyph_infos[c - FIRST_ASCII])
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -168,13 +200,23 @@ impl Font {
|
||||||
/// Returns the start (X) of each character, starting at zero, plus the total width.
|
/// Returns the start (X) of each character, starting at zero, plus the total width.
|
||||||
/// i.e. returns text.chars().count() + 1 numbers.
|
/// i.e. returns text.chars().count() + 1 numbers.
|
||||||
pub fn layout_single_line(&self, text: &str) -> Vec<f32> {
|
pub fn layout_single_line(&self, text: &str) -> Vec<f32> {
|
||||||
|
let scale = Scale::uniform(self.scale as f32);
|
||||||
|
|
||||||
let mut x_offsets = Vec::new();
|
let mut x_offsets = Vec::new();
|
||||||
let mut x = 0.0;
|
let mut cursor_x = 0.0f32;
|
||||||
|
let mut last_glyph_id = None;
|
||||||
for c in text.chars() {
|
for c in text.chars() {
|
||||||
x_offsets.push(x);
|
cursor_x = cursor_x.round();
|
||||||
x += 7.0; // TODO: kerning
|
x_offsets.push(cursor_x);
|
||||||
|
if let Some(glyph) = self.glyph_info(c) {
|
||||||
|
if let Some(last_glyph_id) = last_glyph_id {
|
||||||
|
cursor_x += self.font.pair_kerning(scale, last_glyph_id, glyph.id)
|
||||||
}
|
}
|
||||||
x_offsets.push(x);
|
cursor_x += glyph.advance_width;
|
||||||
|
last_glyph_id = Some(glyph.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x_offsets.push(cursor_x);
|
||||||
x_offsets
|
x_offsets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,28 +231,40 @@ impl Font {
|
||||||
|
|
||||||
pub fn debug_print_all_chars(&self) {
|
pub fn debug_print_all_chars(&self) {
|
||||||
let max_width = 160;
|
let max_width = 160;
|
||||||
|
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];
|
||||||
let mut cursor_x = 0;
|
let mut cursor_x = 0.0;
|
||||||
let mut cursor_y = 0;
|
let mut cursor_y = 0;
|
||||||
|
let mut last_glyph_id = None;
|
||||||
for c in Self::supported_characters() {
|
for c in Self::supported_characters() {
|
||||||
if let Some(glyph_info) = self.glyph_info(c) {
|
if let Some(glyph) = self.glyph_info(c) {
|
||||||
for x in glyph_info.min_x..=glyph_info.max_x {
|
if let Some(last_glyph_id) = last_glyph_id {
|
||||||
for y in glyph_info.min_y..=glyph_info.max_y {
|
cursor_x += self.font.pair_kerning(scale, last_glyph_id, glyph.id)
|
||||||
let pixel = self.pixel(x, y);
|
|
||||||
let rx = glyph_info.offset_x + x - glyph_info.min_x;
|
|
||||||
let ry = glyph_info.offset_y + y - glyph_info.min_y;
|
|
||||||
pixel_rows[cursor_y + ry as usize][cursor_x + rx as usize] = pixel;
|
|
||||||
}
|
}
|
||||||
}
|
if cursor_x + glyph.advance_width >= max_width as f32 {
|
||||||
cursor_x += 7; // TODO
|
|
||||||
if cursor_x + 7 >= max_width {
|
|
||||||
println!("{}", (0..max_width).map(|_| "X").collect::<String>());
|
println!("{}", (0..max_width).map(|_| "X").collect::<String>());
|
||||||
for row in pixel_rows {
|
for row in pixel_rows {
|
||||||
println!("{}", as_ascii(&row));
|
println!("{}", as_ascii(&row));
|
||||||
}
|
}
|
||||||
pixel_rows = vec![vec![0; max_width]; self.scale];
|
pixel_rows = vec![vec![0; max_width]; self.scale];
|
||||||
cursor_x = 0;
|
cursor_x = 0.0;
|
||||||
}
|
}
|
||||||
|
if let Some(uv) = glyph.uv {
|
||||||
|
for x in uv.min_x..=uv.max_x {
|
||||||
|
for y in uv.min_y..=uv.max_y {
|
||||||
|
let pixel = self.pixel(x as u16, y as u16);
|
||||||
|
let rx = uv.offset_x + x as i16 - uv.min_x as i16;
|
||||||
|
let ry = uv.offset_y + y as i16 - uv.min_y as i16;
|
||||||
|
let px = (cursor_x + rx as f32).round();
|
||||||
|
let py = cursor_y + ry;
|
||||||
|
if 0.0 <= px && 0 <= py {
|
||||||
|
pixel_rows[py as usize][px as usize] = pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursor_x += glyph.advance_width;
|
||||||
|
last_glyph_id = Some(glyph.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("{}", (0..max_width).map(|_| "X").collect::<String>());
|
println!("{}", (0..max_width).map(|_| "X").collect::<String>());
|
||||||
|
@ -220,7 +274,19 @@ impl Font {
|
||||||
fn as_ascii(pixels: &[u8]) -> String {
|
fn as_ascii(pixels: &[u8]) -> String {
|
||||||
pixels
|
pixels
|
||||||
.iter()
|
.iter()
|
||||||
.map(|pixel| if *pixel == 0 { ' ' } else { 'X' })
|
.map(|pixel| {
|
||||||
|
if *pixel == 0 {
|
||||||
|
' '
|
||||||
|
} else if *pixel < 85 {
|
||||||
|
'.'
|
||||||
|
} else if *pixel < 170 {
|
||||||
|
'o'
|
||||||
|
} else if *pixel < 255 {
|
||||||
|
'O'
|
||||||
|
} else {
|
||||||
|
'X'
|
||||||
|
}
|
||||||
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,6 @@ use crate::{font::Font, math::*, types::*};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize)]
|
#[derive(Clone, Copy, Debug, Serialize)]
|
||||||
pub struct LayoutOptions {
|
pub struct LayoutOptions {
|
||||||
/// The width and height of a single character (including any spacing).
|
|
||||||
/// All text is monospace!
|
|
||||||
pub char_size: Vec2,
|
|
||||||
|
|
||||||
/// Horizontal and vertical padding within a window frame.
|
/// Horizontal and vertical padding within a window frame.
|
||||||
pub window_padding: Vec2,
|
pub window_padding: Vec2,
|
||||||
|
|
||||||
|
@ -33,7 +29,6 @@ pub struct LayoutOptions {
|
||||||
impl Default for LayoutOptions {
|
impl Default for LayoutOptions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
LayoutOptions {
|
LayoutOptions {
|
||||||
char_size: vec2(7.2, 14.0),
|
|
||||||
item_spacing: vec2(8.0, 4.0),
|
item_spacing: vec2(8.0, 4.0),
|
||||||
window_padding: vec2(6.0, 6.0),
|
window_padding: vec2(6.0, 6.0),
|
||||||
indent: 21.0,
|
indent: 21.0,
|
||||||
|
@ -165,10 +160,10 @@ pub struct Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Layout {
|
impl Layout {
|
||||||
pub fn new() -> Layout {
|
pub fn new(font: Font) -> Layout {
|
||||||
Layout {
|
Layout {
|
||||||
options: Default::default(),
|
options: Default::default(),
|
||||||
font: Font::new(13),
|
font,
|
||||||
input: Default::default(),
|
input: Default::default(),
|
||||||
memory: Default::default(),
|
memory: Default::default(),
|
||||||
id: Default::default(),
|
id: Default::default(),
|
||||||
|
@ -293,7 +288,7 @@ impl Layout {
|
||||||
let (slider_rect, interact) = self.reserve_space(
|
let (slider_rect, interact) = self.reserve_space(
|
||||||
Vec2 {
|
Vec2 {
|
||||||
x: self.options.width,
|
x: self.options.width,
|
||||||
y: self.options.char_size.y,
|
y: self.font.line_spacing(),
|
||||||
},
|
},
|
||||||
Some(id),
|
Some(id),
|
||||||
);
|
);
|
||||||
|
@ -463,7 +458,7 @@ impl Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout_text(&self, text: &str) -> (TextFragments, Vec2) {
|
fn layout_text(&self, text: &str) -> (TextFragments, Vec2) {
|
||||||
let char_size = self.options.char_size;
|
let line_spacing = self.font.line_spacing();
|
||||||
let mut cursor_y = 0.0;
|
let mut cursor_y = 0.0;
|
||||||
let mut max_width = 0.0;
|
let mut max_width = 0.0;
|
||||||
let mut text_fragments = Vec::new();
|
let mut text_fragments = Vec::new();
|
||||||
|
@ -476,7 +471,7 @@ impl Layout {
|
||||||
text: line.into(),
|
text: line.into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
cursor_y += char_size.y;
|
cursor_y += line_spacing;
|
||||||
max_width = line_width.max(max_width);
|
max_width = line_width.max(max_width);
|
||||||
}
|
}
|
||||||
let bounding_size = vec2(max_width, cursor_y);
|
let bounding_size = vec2(max_width, cursor_y);
|
||||||
|
|
|
@ -16,6 +16,7 @@ pub mod types;
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
emgui::Emgui,
|
emgui::Emgui,
|
||||||
|
font::Font,
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
layout::LayoutOptions,
|
layout::LayoutOptions,
|
||||||
painter::{Frame, Painter, Vertex},
|
painter::{Frame, Painter, Vertex},
|
||||||
|
|
|
@ -198,10 +198,8 @@ pub struct Painter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Painter {
|
impl Painter {
|
||||||
pub fn new() -> Painter {
|
pub fn new(font: Font) -> Painter {
|
||||||
Painter {
|
Painter { font }
|
||||||
font: Font::new(13),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 8-bit row-major font atlas texture, (width, height, pixels).
|
/// 8-bit row-major font atlas texture, (width, height, pixels).
|
||||||
|
@ -347,8 +345,8 @@ impl Painter {
|
||||||
x_offsets,
|
x_offsets,
|
||||||
} => {
|
} => {
|
||||||
for (c, x_offset) in text.chars().zip(x_offsets.iter()) {
|
for (c, x_offset) in text.chars().zip(x_offsets.iter()) {
|
||||||
if let Some(glyph) = self.font.glyph_info(c) {
|
if let Some(glyph) = self.font.uv_rect(c) {
|
||||||
let top_left = Vertex {
|
let mut top_left = Vertex {
|
||||||
pos: *pos
|
pos: *pos
|
||||||
+ vec2(
|
+ vec2(
|
||||||
x_offset + (glyph.offset_x as f32),
|
x_offset + (glyph.offset_x as f32),
|
||||||
|
@ -357,6 +355,8 @@ impl Painter {
|
||||||
uv: (glyph.min_x, glyph.min_y),
|
uv: (glyph.min_x, glyph.min_y),
|
||||||
color: *color,
|
color: *color,
|
||||||
};
|
};
|
||||||
|
top_left.pos.x = top_left.pos.x.round(); // Pixel-perfection.
|
||||||
|
top_left.pos.y = top_left.pos.y.round(); // Pixel-perfection.
|
||||||
let bottom_right = Vertex {
|
let bottom_right = Vertex {
|
||||||
pos: top_left.pos
|
pos: top_left.pos
|
||||||
+ vec2(
|
+ vec2(
|
||||||
|
|
|
@ -96,8 +96,6 @@ impl GuiSettings for emgui::LayoutOptions {
|
||||||
if gui.button("Reset LayoutOptions").clicked {
|
if gui.button("Reset LayoutOptions").clicked {
|
||||||
*self = Default::default();
|
*self = Default::default();
|
||||||
}
|
}
|
||||||
gui.slider_f32("char_size.x", &mut self.char_size.x, 0.0, 20.0);
|
|
||||||
gui.slider_f32("char_size.y", &mut self.char_size.y, 0.0, 20.0);
|
|
||||||
gui.slider_f32("item_spacing.x", &mut self.item_spacing.x, 0.0, 10.0);
|
gui.slider_f32("item_spacing.x", &mut self.item_spacing.x, 0.0, 10.0);
|
||||||
gui.slider_f32("item_spacing.y", &mut self.item_spacing.y, 0.0, 10.0);
|
gui.slider_f32("item_spacing.y", &mut self.item_spacing.y, 0.0, 10.0);
|
||||||
gui.slider_f32("window_padding.x", &mut self.window_padding.x, 0.0, 10.0);
|
gui.slider_f32("window_padding.x", &mut self.window_padding.x, 0.0, 10.0);
|
||||||
|
|
|
@ -9,7 +9,7 @@ extern crate emgui;
|
||||||
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use emgui::{Emgui, Frame, RawInput};
|
use emgui::{Emgui, Font, Frame, RawInput};
|
||||||
|
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
@ -42,9 +42,13 @@ mod webgl;
|
||||||
// serde_json::to_string(&commands).unwrap()
|
// serde_json::to_string(&commands).unwrap()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
fn font() -> Font {
|
||||||
|
Font::new(20) // TODO: don't create this multiple times
|
||||||
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn new_webgl_painter(canvas_id: &str) -> Result<webgl::Painter, JsValue> {
|
pub fn new_webgl_painter(canvas_id: &str) -> Result<webgl::Painter, JsValue> {
|
||||||
let emgui_painter = emgui::Painter::new(); // TODO: don't create this twice
|
let emgui_painter = emgui::Painter::new(font()); // TODO: don't create this twice
|
||||||
webgl::Painter::new(canvas_id, emgui_painter.texture())
|
webgl::Painter::new(canvas_id, emgui_painter.texture())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,8 +62,8 @@ impl State {
|
||||||
fn new() -> State {
|
fn new() -> State {
|
||||||
State {
|
State {
|
||||||
app: Default::default(),
|
app: Default::default(),
|
||||||
emgui: Emgui::new(),
|
emgui: Emgui::new(font()),
|
||||||
emgui_painter: emgui::Painter::new(),
|
emgui_painter: emgui::Painter::new(font()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,8 @@ impl Painter {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_WRAP_S, Gl::CLAMP_TO_EDGE as i32);
|
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_WRAP_S, Gl::CLAMP_TO_EDGE as i32);
|
||||||
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_WRAP_T, Gl::CLAMP_TO_EDGE as i32);
|
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_WRAP_T, Gl::CLAMP_TO_EDGE as i32);
|
||||||
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_MIN_FILTER, Gl::NEAREST as i32);
|
// gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_MIN_FILTER, Gl::NEAREST as i32);
|
||||||
|
gl.tex_parameteri(Gl::TEXTURE_2D, Gl::TEXTURE_MIN_FILTER, Gl::LINEAR as i32);
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue