mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2024-11-22 13:42:47 +00:00
minimalist bmfont loader
This commit is contained in:
parent
a82a53201e
commit
c21eb248ba
109
src/bmfont.rs
Normal file
109
src/bmfont.rs
Normal file
|
@ -0,0 +1,109 @@
|
|||
use std::collections::HashMap;
|
||||
use std::io;
|
||||
|
||||
use byteorder::{LE, ReadBytesExt};
|
||||
|
||||
use crate::ggez::GameError::ResourceLoadError;
|
||||
use crate::ggez::GameResult;
|
||||
use crate::str;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BmChar {
|
||||
pub x: u16,
|
||||
pub y: u16,
|
||||
pub width: u16,
|
||||
pub height: u16,
|
||||
pub xoffset: i16,
|
||||
pub yoffset: i16,
|
||||
pub xadvance: i16,
|
||||
pub page: u8,
|
||||
pub chnl: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BmFont {
|
||||
pub pages: u16,
|
||||
pub font_size: i16,
|
||||
pub line_height: u16,
|
||||
pub base: u16,
|
||||
pub chars: HashMap<char, BmChar>,
|
||||
}
|
||||
|
||||
const MAGIC: [u8; 4] = [b'B', b'M', b'F', 3];
|
||||
|
||||
impl BmFont {
|
||||
pub fn load_from<R: io::Read + io::Seek>(mut data: R) -> GameResult<Self> {
|
||||
let mut magic = [0u8; 4];
|
||||
let mut pages = 0u16;
|
||||
let mut chars = HashMap::with_capacity(128);
|
||||
let mut font_size = 0i16;
|
||||
let mut line_height = 0u16;
|
||||
let mut base = 0u16;
|
||||
|
||||
data.read_exact(&mut magic)?;
|
||||
|
||||
if magic != MAGIC {
|
||||
return Err(ResourceLoadError(str!( "Invalid magic")));
|
||||
}
|
||||
|
||||
while let Ok(block_type) = data.read_u8() {
|
||||
let length = data.read_u32::<LE>()?;
|
||||
match block_type {
|
||||
1 => {
|
||||
font_size = data.read_i16::<LE>()?;
|
||||
|
||||
data.seek(io::SeekFrom::Current(length as i64 - 2))?;
|
||||
}
|
||||
2 => {
|
||||
line_height = data.read_u16::<LE>()?;
|
||||
base = data.read_u16::<LE>()?;
|
||||
data.seek(io::SeekFrom::Current(4))?;
|
||||
pages = data.read_u16::<LE>()?;
|
||||
|
||||
data.seek(io::SeekFrom::Current(length as i64 - 10))?;
|
||||
}
|
||||
3 | 5 => {
|
||||
data.seek(io::SeekFrom::Current(length as i64))?;
|
||||
}
|
||||
4 => {
|
||||
let count = length / 20;
|
||||
for _ in 0..count {
|
||||
let id = data.read_u32::<LE>()?;
|
||||
let x = data.read_u16::<LE>()?;
|
||||
let y = data.read_u16::<LE>()?;
|
||||
let width = data.read_u16::<LE>()?;
|
||||
let height = data.read_u16::<LE>()?;
|
||||
let xoffset = data.read_i16::<LE>()?;
|
||||
let yoffset = data.read_i16::<LE>()?;
|
||||
let xadvance = data.read_i16::<LE>()?;
|
||||
let page = data.read_u8()?;
|
||||
let chnl = data.read_u8()?;
|
||||
|
||||
if let Some(chr) = std::char::from_u32(id) {
|
||||
chars.insert(chr, BmChar {
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
xoffset,
|
||||
yoffset,
|
||||
xadvance,
|
||||
page,
|
||||
chnl,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => { return Err(ResourceLoadError(str!( "Unknown block type."))); }
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
pages,
|
||||
font_size,
|
||||
line_height,
|
||||
base,
|
||||
chars,
|
||||
})
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@ use log::*;
|
|||
use pretty_env_logger::env_logger::Env;
|
||||
use winit::{ElementState, Event, KeyboardInput, WindowEvent};
|
||||
|
||||
use crate::builtin_fs::BuiltinFS;
|
||||
use crate::caret::{Caret, CaretType};
|
||||
use crate::common::{Direction, FadeState};
|
||||
use crate::engine_constants::EngineConstants;
|
||||
|
@ -40,8 +41,8 @@ use crate::stage::StageData;
|
|||
use crate::text_script::TextScriptVM;
|
||||
use crate::texture_set::TextureSet;
|
||||
use crate::ui::UI;
|
||||
use crate::builtin_fs::BuiltinFS;
|
||||
|
||||
mod bmfont;
|
||||
mod builtin_fs;
|
||||
mod caret;
|
||||
mod common;
|
||||
|
|
Loading…
Reference in a new issue