Initialize Minecraft text generator project with basic structure and CLI functionality
This commit is contained in:
91
crates/lib/src/engine.rs
Normal file
91
crates/lib/src/engine.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
use crate::{font::FontProvider, grid::VoxelGrid, models::VoxelType};
|
||||
|
||||
pub struct GenerationOptions {
|
||||
pub extrusion_depth: u32,
|
||||
pub generate_outline: bool,
|
||||
// Future options can be added here, such as:
|
||||
// shadow, scale, italics, etc.
|
||||
}
|
||||
|
||||
impl Default for GenerationOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
extrusion_depth: 1,
|
||||
generate_outline: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TextBuilder<'a> {
|
||||
font: &'a dyn FontProvider,
|
||||
options: GenerationOptions,
|
||||
}
|
||||
|
||||
impl<'a> TextBuilder<'a> {
|
||||
pub fn new(font: &'a dyn FontProvider) -> Self {
|
||||
Self {
|
||||
font,
|
||||
options: GenerationOptions::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_depth(mut self, depth: u32) -> Self {
|
||||
self.options.extrusion_depth = depth.max(1);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_outline(mut self, generate: bool) -> Self {
|
||||
self.options.generate_outline = generate;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn generate(&self, text: &str) -> VoxelGrid {
|
||||
let mut total_width = 0;
|
||||
let mut max_height = 0;
|
||||
let mut glyphs_to_render = Vec::new();
|
||||
|
||||
for c in text.chars() {
|
||||
if let Some(glyph) = self.font.get_glyph(c) {
|
||||
total_width += glyph.width + self.font.letter_spacing();
|
||||
max_height = max_height.max(glyph.height);
|
||||
glyphs_to_render.push(glyph);
|
||||
}
|
||||
}
|
||||
|
||||
let padding = if self.options.generate_outline { 2 } else { 0 };
|
||||
|
||||
let mut grid = VoxelGrid::new(
|
||||
total_width + padding,
|
||||
max_height + padding,
|
||||
self.options.extrusion_depth,
|
||||
);
|
||||
|
||||
let mut current_x = if self.options.generate_outline { 1 } else { 0 };
|
||||
let base_y = if self.options.generate_outline { 1 } else { 0 };
|
||||
|
||||
for glyph in glyphs_to_render {
|
||||
for gy in 0..glyph.height {
|
||||
for gx in 0..glyph.width {
|
||||
let glyph_index = (gy * glyph.width + gx) as usize;
|
||||
|
||||
if glyph.data[glyph_index] {
|
||||
let world_x = current_x + gx;
|
||||
let world_y = base_y + (glyph.height - 1 - gy); // Flip vertically
|
||||
|
||||
for z in 0..self.options.extrusion_depth {
|
||||
if let Err(e) = grid.set(world_x, world_y, z, VoxelType::Body) {
|
||||
tracing::warn!("failed to set voxel: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current_x += glyph.width + self.font.letter_spacing();
|
||||
}
|
||||
|
||||
// TODO: Add outline generation logic here if self.options.generate_outline is true.
|
||||
|
||||
grid
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user