Moved a tonne of code around
This commit is contained in:
@ -1,209 +0,0 @@
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
void fontDispose(font_t *font) {
|
||||
textureDispose(&font->texture);
|
||||
}
|
||||
|
||||
float fontGetScale(float fontSize) {
|
||||
return fontSize / FONT_SIZE_DEFAULT * FONT_GLOBAL_SCALE;
|
||||
}
|
||||
|
||||
bool _fontTextBufferAddLine(fonttextinfo_t *info, int32_t start, int32_t len) {
|
||||
info->lineCount++;
|
||||
|
||||
if(info->lineCount >= FONT_TEXT_INFO_LINES_MAX) {
|
||||
return false;
|
||||
}
|
||||
|
||||
info->lines[info->lineCount].start = start;
|
||||
info->lines[info->lineCount].length = len;
|
||||
return true;
|
||||
}
|
||||
|
||||
void fontTextBuffer(
|
||||
font_t *font, primitive_t *primitive, fonttextinfo_t *info, char *text,
|
||||
float maxWidth, float fontSize
|
||||
) {
|
||||
int32_t i, j, wordStart;
|
||||
char c;
|
||||
float x, y, wordX, scale;
|
||||
stbtt_aligned_quad *quads;
|
||||
stbtt_aligned_quad *quad;
|
||||
|
||||
// Make some space
|
||||
quads = malloc(sizeof(stbtt_aligned_quad) * strlen(text));
|
||||
|
||||
// Get the font scale
|
||||
scale = fontGetScale(fontSize);
|
||||
|
||||
// Adjust the max width to match the scale, and allow "no max width".
|
||||
maxWidth = maxWidth == -1 ? 9999999 : maxWidth * (1 / scale);
|
||||
|
||||
/** Which index in the original text var is the current word from */
|
||||
wordStart = 0;
|
||||
|
||||
// Setup Scales
|
||||
info->length = 0;
|
||||
info->realLength = 0;
|
||||
info->lineCount = 0;
|
||||
|
||||
// Prepare the line counters
|
||||
info->lines[0].start = 0;
|
||||
info->lines[0].length = 0;
|
||||
|
||||
// Reset Dimensions
|
||||
info->width = 0, info->height = 0;
|
||||
|
||||
// Setup the initial loop state, and X/Y coords for the quad.
|
||||
i = 0;
|
||||
x = 0;
|
||||
y = FONT_INITIAL_LINE;
|
||||
wordX = 0;
|
||||
while(c = text[i++]) {
|
||||
if(info->lineCount >= FONT_TEXT_INFO_LINES_MAX) break;
|
||||
info->length++;
|
||||
|
||||
// When space, start of new word about to begin
|
||||
if(c == FONT_SPACE) {
|
||||
x += FONT_SPACE_SIZE * scale;
|
||||
|
||||
// Did this space cause a newline?
|
||||
if(x > maxWidth) {
|
||||
_fontTextBufferAddLine(info, info->realLength, 0);
|
||||
y += FONT_LINE_HEIGHT;
|
||||
x = 0;
|
||||
}
|
||||
wordX = x;
|
||||
wordStart = info->realLength;
|
||||
continue;
|
||||
}
|
||||
|
||||
// New line.
|
||||
if(c == FONT_NEWLINE) {
|
||||
_fontTextBufferAddLine(info, info->realLength, 0);
|
||||
wordStart = info->realLength;
|
||||
y += FONT_LINE_HEIGHT;
|
||||
x = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Generate the quad.
|
||||
quad = quads + info->realLength;
|
||||
stbtt_GetBakedQuad(font->characterData,
|
||||
FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT,
|
||||
((int32_t)c)-FONT_FIRST_CHAR, &x, &y, quad, FONT_FILL_MODE
|
||||
);
|
||||
|
||||
// Now measure the width of the line (take the right side of that quad)
|
||||
if(quad->x1 > maxWidth) {
|
||||
// We've exceeded the edge, go back to the start of the word and newline.
|
||||
x = quad->x1 - wordX;
|
||||
for(j = wordStart; j <= info->realLength; j++) {
|
||||
quad = quads + j;
|
||||
quad->x0 -= wordX;
|
||||
quad->x1 -= wordX;
|
||||
quad->y0 += FONT_LINE_HEIGHT;
|
||||
quad->y1 += FONT_LINE_HEIGHT;
|
||||
}
|
||||
|
||||
// Go back to the previous (still current) line and remove the chars
|
||||
info->lines[info->lineCount].length -= info->realLength - wordStart;
|
||||
|
||||
// Next line begins with this word
|
||||
y += FONT_LINE_HEIGHT;
|
||||
if(!_fontTextBufferAddLine(info, wordStart, info->realLength-wordStart)) {
|
||||
continue;
|
||||
}
|
||||
wordX = 0;
|
||||
}
|
||||
|
||||
info->lines[info->lineCount].length++;
|
||||
info->realLength++;
|
||||
}
|
||||
|
||||
info->lineCount++;
|
||||
|
||||
// Initialize primitive
|
||||
primitiveInit(primitive,
|
||||
QUAD_VERTICE_COUNT * info->realLength,
|
||||
QUAD_INDICE_COUNT * info->realLength
|
||||
);
|
||||
|
||||
for(j = 0; j < info->realLength; j++) {
|
||||
quad = quads + j;
|
||||
|
||||
// Scale the Quad
|
||||
if(scale != 1.0) {
|
||||
quad->x0 *= scale;
|
||||
quad->x1 *= scale;
|
||||
quad->y0 *= scale;
|
||||
quad->y1 *= scale;
|
||||
}
|
||||
|
||||
// Update the dimensions.
|
||||
info->width = mathMax(info->width, quad->x1);
|
||||
info->height = mathMax(info->height, quad->y1);
|
||||
|
||||
// Buffer the quad.
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
// Free up
|
||||
free(quads);
|
||||
}
|
||||
|
||||
int32_t fontGetLineCharCount(fonttextinfo_t *info,int32_t start,int32_t count) {
|
||||
int32_t charCount, i, m;
|
||||
m = mathMin(start+count, info->lineCount);
|
||||
|
||||
charCount = 0;
|
||||
for(i = start; i < m; i++) {
|
||||
charCount += info->lines[i].length;
|
||||
}
|
||||
|
||||
return charCount;
|
||||
}
|
Reference in New Issue
Block a user