147 lines
3.4 KiB
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);
|
|
} |