[oden] Text is mildly functional

This commit is contained in:
John Doty 2023-08-31 17:18:37 -07:00
parent 8914b1795f
commit ecce7b64eb
5 changed files with 204 additions and 114 deletions

View file

@ -46,6 +46,8 @@ pub struct FontCache {
font: Font,
size: f32,
texture: wgpu::Texture,
cell_width: u16,
cell_height: u16,
pub view: wgpu::TextureView,
pub sampler: wgpu::Sampler,
@ -69,8 +71,11 @@ struct GlyphCell {
pub struct Glyph {
pub x: f32,
pub y: f32,
pub adjust_x: f32,
pub adjust_y: f32,
pub w: f32,
pub h: f32,
pub advance_width: f32,
}
impl FontCache {
@ -90,7 +95,7 @@ impl FontCache {
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 4,
sample_count: 1, // 4 for multisample?
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::R8Unorm,
usage: wgpu::TextureUsages::TEXTURE_BINDING
@ -124,6 +129,8 @@ impl FontCache {
char_width = metrics.width.max(char_width);
char_height = metrics.height.max(char_height);
eprintln!("For this font, width={char_width} height={char_height}");
// Allocate the individual cells in the texture atlas; this records
// the state of what's in the cell and whatnot.
let mut cells = vec![];
@ -151,6 +158,9 @@ impl FontCache {
font,
size,
texture,
cell_width: char_width.try_into().unwrap(),
cell_height: char_height.try_into().unwrap(),
view,
sampler,
cells,
@ -182,9 +192,33 @@ impl FontCache {
SlotState::Empty => {
let (metrics, bitmap) = self.font.rasterize_indexed(index, self.size);
// eprintln!("Rasterizing '{c}' (index {index}): {metrics:?}");
// For a good time, call
// {
// eprintln!();
// let mut i = 0;
// for _ in (0..metrics.height) {
// for _ in (0..metrics.width) {
// let bv = bitmap[i];
// let rc = if bv == 0 {
// ' '
// } else if bv < 25 {
// '.'
// } else {
// 'X'
// };
// eprint!("{rc}");
// i += 1;
// }
// eprintln!();
// }
// eprintln!();
// }
let mut texture = self.texture.as_image_copy();
texture.origin.x = cell.x.into();
texture.origin.y = cell.y.into();
// eprintln!(" Rendering to {}, {}", texture.origin.x, texture.origin.y);
queue.write_texture(
texture,
@ -207,14 +241,44 @@ impl FontCache {
};
Glyph {
x: cell.x as f32 + metrics.bounds.xmin,
y: cell.y as f32 + metrics.bounds.ymin,
w: metrics.bounds.width,
h: metrics.bounds.height,
x: cell.x as f32,
y: cell.y as f32,
adjust_x: metrics.xmin as f32,
adjust_y: (self.cell_height as f32)
+ floor(-metrics.bounds.height - metrics.bounds.ymin), // PositiveYDown,
w: self.cell_width as f32,
h: self.cell_height as f32,
advance_width: metrics.advance_width,
}
}
}
fn floor(x: f32) -> f32 {
let mut ui = x.to_bits();
let e = (((ui >> 23) as i32) & 0xff) - 0x7f;
if e >= 23 {
return x;
}
if e >= 0 {
let m: u32 = 0x007fffff >> e;
if (ui & m) == 0 {
return x;
}
if ui >> 31 != 0 {
ui += m;
}
ui &= !m;
} else {
if ui >> 31 == 0 {
ui = 0;
} else if ui << 1 != 0 {
return -1.0;
}
}
f32::from_bits(ui)
}
// pub fn inconsolata() {
// let font = include_bytes!("./Inconsolata-Regular.ttf") as &[u8];
// let font = fontdue::Font::from_bytes(font, fontdue::FontSettings::default()).unwrap();