#include "local.h"
#include <alias/str.h>
#define FONT_DRAW_CHARACTERS_PER_BATCH 1024
const struct FontGlyph *Font_find_glyph(const struct Font *font, const char *text) {
char32_t c = *text;
for(uint32_t i = 0; i < font->num_glyphs; i++) {
if(font->glyphs[i].codepoint == c) {
return &font->glyphs[i];
}
}
return &font->glyphs[0];
}
void Font_draw(struct Font *font, const char *text, float x, float y, float size, float spacing, alias_Color color) {
struct BackendUIVertex *vertexes = NULL;
uint32_t *indexes = NULL;
uint32_t i = 0;
size_t length = alias_str_length(text);
struct BackendImage *image = &Engine__load_image(&font->atlas)->image;
float s_scale = alias_R_ONE / image->width;
float t_scale = alias_R_ONE / image->height;
while(*text) {
if(i == 0) {
BackendUIVertex_begin_draw(6 * alias_min(FONT_DRAW_CHARACTERS_PER_BATCH, length), &indexes,
4 * alias_min(FONT_DRAW_CHARACTERS_PER_BATCH, length), &vertexes);
}
const struct FontGlyph *glyph = Font_find_glyph(font, text);
text++;
#define EMIT(I, V, H) \
vertexes[i * 4 + I].xy[0] = x + glyph->plane_##H * size; \
vertexes[i * 4 + I].xy[1] = y + (1.0f - glyph->plane_##V) * size; \
vertexes[i * 4 + I].rgba[0] = color.r; \
vertexes[i * 4 + I].rgba[1] = color.g; \
vertexes[i * 4 + I].rgba[2] = color.b; \
vertexes[i * 4 + I].rgba[3] = color.a; \
vertexes[i * 4 + I].st[0] = glyph->atlas_##H * s_scale; \
vertexes[i * 4 + I].st[1] = 1.0f - (glyph->atlas_##V * t_scale);
EMIT(0, bottom, left)
EMIT(1, bottom, right)
EMIT(2, top, right)
EMIT(3, top, left)
#undef EMIT
indexes[i * 6 + 0] = i * 4 + 0;
indexes[i * 6 + 1] = i * 4 + 2;
indexes[i * 6 + 2] = i * 4 + 1;
indexes[i * 6 + 3] = i * 4 + 2;
indexes[i * 6 + 4] = i * 4 + 0;
indexes[i * 6 + 5] = i * 4 + 3;
x += glyph->advance * size + spacing;
i++;
length--;
if(i >= FONT_DRAW_CHARACTERS_PER_BATCH) {
BackendUIVertex_draw(image, 0, 6 * FONT_DRAW_CHARACTERS_PER_BATCH);
BackendUIVertex_end_draw();
i = 0;
}
}
if(i >= 0) {
BackendUIVertex_draw(image, 0, 6 * i);
BackendUIVertex_end_draw();
}
}
void Font_measure(struct Font *font, const char *text, float size, float spacing, float *width, float *height) {
*height = size;
*width = 0;
while(*text) {
const struct FontGlyph *glyph = Font_find_glyph(font, text);
text++;
(*width) += glyph->advance * size + spacing;
}
}