Dawn/src/display/gui/font.c

147 lines
3.4 KiB
C

/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "font.h"
// Due to some compiler bullshit, this is here.
#ifndef STB_TRUETYPE_IMPLEMENTATION
#define STB_TRUETYPE_IMPLEMENTATION
#include <stb_truetype.h>
#endif
void fontInit(font_t *font, char *data) {
int32_t i, s;
s = FONT_TEXTURE_WIDTH * FONT_TEXTURE_HEIGHT;
uint8_t *bitmapData = malloc(sizeof(uint8_t) * s);
pixel_t *pixels = malloc(sizeof(pixel_t) * s);
// STBTT Loads fonts as single channel values only.
stbtt_BakeFontBitmap(
data, 0, FONT_TEXTURE_SIZE, bitmapData,
FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT,
FONT_FIRST_CHAR, FONT_NUM_CHARS,
font->characterData
);
for(i = 0; i < FONT_TEXTURE_WIDTH * FONT_TEXTURE_HEIGHT; i++) {
pixels[i].r = 0xFF;
pixels[i].g = 0xFF;
pixels[i].b = 0xFF;
pixels[i].a = bitmapData[i];
}
textureInit(&font->texture, FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT, pixels);
free(bitmapData);
free(pixels);
}
fonttextinfo_t fontGetTextInfo(font_t *font, char *text) {
float x, y;
char c;
int32_t i;
fonttextinfo_t info = {
.length = 0,
.realChars = 0,
.lineHeight = FONT_LINE_HEIGHT,
.spaceSize = FONT_SPACE_SIZE
};
// Count how many "real characters" are in the string.
i = 0;
while(c = text[i++]) {
info.length++;
if(c == FONT_SPACE) continue;
if(c == FONT_NEWLINE) continue;
info.realChars++;
}
return info;
}
fontmeasure_t * fontTextMeasure(font_t *font, char *text, fonttextinfo_t *info,
float scale
) {
int32_t i, j;
char c;
float x, y;
stbtt_aligned_quad *quad;
fontmeasure_t *measure;
scale *= FONT_SCALE_ADJUST;
measure = malloc(sizeof(fontmeasure_t));
measure->scale = scale;
measure->quads = malloc(sizeof(stbtt_aligned_quad) * info->realChars);
x = 0;
y = FONT_INITIAL_LINE;
i = 0, j = 0;
while(c = text[i++]) {
if(c == FONT_SPACE) {
x += info->spaceSize;
continue;
}
if(c == FONT_NEWLINE) {
y += info->lineHeight;
x = 0;
continue;
}
// Calculate the quad of the character, store into the array.
quad = measure->quads + j;
stbtt_GetBakedQuad(font->characterData,
FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT,
((int32_t)c)-FONT_FIRST_CHAR, &x, &y, quad, FONT_FILL_MODE
);
quad->x0 *= scale, quad->x1 *= scale;
quad->y0 *= scale, quad->y1 *= scale;
j++;
}
return measure;
}
void fontTextMeasureDispose(fontmeasure_t *measure) {
free(measure->quads);
free(measure);
}
void fontDispose(font_t *font) {
textureDispose(&font->texture);
}
void fontTextBufferFromMeasure(font_t *font, primitive_t *primitive, char *text,
fontmeasure_t *measure
) {
stbtt_aligned_quad *quad;
int32_t i, j;
char c;
i = 0, j = 0;
while(c = text[i++]) {
if(c == FONT_SPACE) continue;
if(c == FONT_NEWLINE) continue;
quad = measure->quads + j;
quadBuffer(primitive, 0,
quad->x0, quad->y0, quad->s0, quad->t0,
quad->x1, quad->y1, quad->s1, quad->t1,
j*QUAD_VERTICE_COUNT, j*QUAD_INDICE_COUNT
);
j++;
}
}
void fontTextInitFromMeasure(font_t *font, primitive_t *primitive, char *text,
fonttextinfo_t *info, fontmeasure_t *measure
) {
primitiveInit(primitive,
QUAD_VERTICE_COUNT*info->realChars, QUAD_INDICE_COUNT*info->realChars
);
fontTextBufferFromMeasure(font, primitive, text, measure);
}