mirror of
https://github.com/lisk77/comet.git
synced 2025-10-25 06:18:49 +00:00
feat: text can now be rendered, though only in the setup right now (will make a new render pass for that)
This commit is contained in:
parent
0507703284
commit
b2578f7673
3 changed files with 215 additions and 117 deletions
|
|
@ -1,17 +1,31 @@
|
|||
use image::{DynamicImage, Rgba, RgbaImage};
|
||||
use ab_glyph::{FontArc, PxScale, ScaleFont, Glyph, point, Font as AbFont};
|
||||
use comet_log::debug;
|
||||
use crate::texture_atlas::{TextureAtlas, TextureRegion};
|
||||
|
||||
pub struct GlyphData {
|
||||
pub name: String,
|
||||
pub render: DynamicImage,
|
||||
pub advance: f32,
|
||||
pub offset_x: f32,
|
||||
pub offset_y: f32,
|
||||
}
|
||||
|
||||
pub struct Font {
|
||||
name: String,
|
||||
size: f32,
|
||||
line_height: f32,
|
||||
glyphs: TextureAtlas,
|
||||
}
|
||||
|
||||
impl Font {
|
||||
pub fn new(path: &str, size: f32) -> Self {
|
||||
let (glyphs, line_height) = Self::generate_atlas(path, size);
|
||||
Font {
|
||||
name: path.to_string(),
|
||||
glyphs: Self::generate_atlas(path, size)
|
||||
size,
|
||||
line_height,
|
||||
glyphs
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -19,6 +33,14 @@ impl Font {
|
|||
&self.name
|
||||
}
|
||||
|
||||
pub fn size(&self) -> f32 {
|
||||
self.size
|
||||
}
|
||||
|
||||
pub fn line_height(&self) -> f32 {
|
||||
self.line_height
|
||||
}
|
||||
|
||||
pub fn glyphs(&self) -> &TextureAtlas {
|
||||
&self.glyphs
|
||||
}
|
||||
|
|
@ -27,31 +49,41 @@ impl Font {
|
|||
self.glyphs.textures().get(&ch.to_string())
|
||||
}
|
||||
|
||||
fn generate_atlas(path: &str, size: f32) -> TextureAtlas {
|
||||
fn generate_atlas(path: &str, size: f32) -> (TextureAtlas, f32) {
|
||||
let font_data = std::fs::read(path).expect("Failed to read font file");
|
||||
let font = FontArc::try_from_vec(font_data).expect("Failed to load font");
|
||||
|
||||
let scale = PxScale::from(size);
|
||||
let scaled_font = font.as_scaled(scale);
|
||||
|
||||
let mut names = Vec::new();
|
||||
let mut images = Vec::new();
|
||||
let mut glyphs: Vec<GlyphData> = Vec::new();
|
||||
|
||||
for code_point in 0x0020..=0x007E {
|
||||
if let Some(ch) = std::char::from_u32(code_point) {
|
||||
if font.glyph_id(ch).0 == 0 {
|
||||
let glyph_id = font.glyph_id(ch);
|
||||
if glyph_id.0 == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
names.push(ch.to_string());
|
||||
if ch == ' ' {
|
||||
let advance = scaled_font.h_advance(glyph_id);
|
||||
glyphs.push(GlyphData {
|
||||
name: ch.to_string(),
|
||||
render: DynamicImage::new_rgba8(0, 0), // no bitmap
|
||||
advance,
|
||||
offset_x: 0.0,
|
||||
offset_y: 0.0,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
let glyph = Glyph {
|
||||
id: font.glyph_id(ch),
|
||||
id: glyph_id,
|
||||
scale,
|
||||
position: point(0.0, 0.0),
|
||||
};
|
||||
|
||||
if let Some(outline) = scaled_font.outline_glyph(glyph) {
|
||||
if let Some(outline) = scaled_font.outline_glyph(glyph.clone()) {
|
||||
let bounds = outline.px_bounds();
|
||||
let width = bounds.width().ceil() as u32;
|
||||
let height = bounds.height().ceil() as u32;
|
||||
|
|
@ -70,11 +102,19 @@ impl Font {
|
|||
image.put_pixel(x, y, Rgba([255, 255, 255, alpha]));
|
||||
});
|
||||
|
||||
images.push(DynamicImage::ImageRgba8(image));
|
||||
glyphs.push(
|
||||
GlyphData {
|
||||
name: ch.to_string(),
|
||||
render: DynamicImage::ImageRgba8(image),
|
||||
advance: scaled_font.h_advance(glyph_id),
|
||||
offset_x: bounds.min.x,
|
||||
offset_y: bounds.min.y,
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextureAtlas::from_textures(names, images)
|
||||
(TextureAtlas::from_glyphs(glyphs), scaled_font.ascent() - scaled_font.descent())
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue