/** * 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 #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); }