108 lines
2.4 KiB
TypeScript
108 lines
2.4 KiB
TypeScript
import { AssetManager } from "../assets.ts";
|
|
import { flush_batch, get_current_texture, push_quad, set_current_texture } from "./core.ts";
|
|
import { FntChar, FntFont, Texture } from "./types.ts";
|
|
|
|
let font_texture: Texture;
|
|
let font_fnt: FntFont;
|
|
|
|
export function init_font() {
|
|
font_texture = AssetManager.instance.get<Texture>("bworld:m6x11");
|
|
|
|
font_fnt = parse_fnt(AssetManager.instance.get("bworld:m6x11_fnt"));
|
|
}
|
|
|
|
function parse_fnt(text: string): FntFont {
|
|
const lines = text.split(/\r?\n/);
|
|
|
|
const font: FntFont = {
|
|
line_height: 0,
|
|
chars: {},
|
|
pages: [],
|
|
};
|
|
|
|
for (const line of lines) {
|
|
const parts = line.split(" ");
|
|
const type = parts[0];
|
|
|
|
const data: Record<string, string> = {};
|
|
|
|
for (const part of parts.slice(1)) {
|
|
const [k, v] = part.split("=");
|
|
if (!k) {
|
|
continue;
|
|
}
|
|
data[k] = v?.replace(/"/g, "");
|
|
}
|
|
|
|
if (type === "common") {
|
|
font.line_height = Number(data.lineHeight);
|
|
}
|
|
|
|
if (type === "page") {
|
|
font.pages.push(data.file);
|
|
}
|
|
|
|
if (type === "char") {
|
|
const char: FntChar = {
|
|
id: Number(data.id),
|
|
x: Number(data.x),
|
|
y: Number(data.y),
|
|
width: Number(data.width),
|
|
height: Number(data.height),
|
|
xoffset: Number(data.xoffset),
|
|
yoffset: Number(data.yoffset),
|
|
xadvance: Number(data.xadvance),
|
|
page: Number(data.page),
|
|
};
|
|
|
|
font.chars[char.id] = char;
|
|
}
|
|
}
|
|
|
|
return font;
|
|
}
|
|
|
|
export function draw_text(str: string, x: number, y: number, scale: number = 1, color = [1, 1, 1, 1]) {
|
|
if (!font_texture) {
|
|
return;
|
|
}
|
|
|
|
if (get_current_texture() !== font_texture.tex) {
|
|
flush_batch();
|
|
set_current_texture(font_texture.tex);
|
|
}
|
|
|
|
for (const ch of str) {
|
|
const glyph = font_fnt.chars[ch.charCodeAt(0)];
|
|
if (!glyph) {
|
|
continue;
|
|
}
|
|
|
|
const dx = x + glyph.xoffset * scale;
|
|
const dy = y + glyph.yoffset * scale;
|
|
const dw = glyph.width * scale;
|
|
const dh = glyph.height * scale;
|
|
|
|
const u0 = glyph.x / font_texture.width;
|
|
const v0 = glyph.y / font_texture.height;
|
|
const u1 = (glyph.x + glyph.width) / font_texture.width;
|
|
const v1 = (glyph.y + glyph.height) / font_texture.height;
|
|
|
|
push_quad(dx, dy, dw, dh, u0, v0, u1, v1, color[0], color[1], color[2], color[3]);
|
|
|
|
x += glyph.xadvance * scale;
|
|
}
|
|
}
|
|
|
|
export function measure_text(str: string, scale: number = 1) {
|
|
let x = 0;
|
|
for (const ch of str) {
|
|
const glyph = font_fnt.chars[ch.charCodeAt(0)];
|
|
if (!glyph) {
|
|
continue;
|
|
}
|
|
x += glyph.xadvance * scale;
|
|
}
|
|
return x;
|
|
}
|