Significantly improved font code

This commit is contained in:
2021-05-24 20:56:50 -07:00
parent 402ebcf05f
commit 388d94cbcc
5 changed files with 71 additions and 104 deletions

View File

@ -1,2 +1,7 @@
- Make font measure take in a pointer to a primitive to offer auto buffering of verts
- Make a clone of the string into font measure pointing only to real chars?
- Make a clone of the string into font measure pointing only to real chars?
- How to do text wrapping efficiently?
- Two pointers, one for current char and one for the last known text position.
- Start by measuring whole string, this will give me n chars and let me know straight away if text fits
- Half divide the pointer to try and find the mid point and figure out if I should go up or down, keep halfing until finding the below then iterate up

View File

@ -41,11 +41,7 @@ typedef struct {
typedef struct {
int32_t length;
int32_t realChars;
float lineHeight, spaceSize;
} fonttextinfo_t;
typedef struct {
int32_t realLength;
float width, height, scale;
stbtt_aligned_quad *quads;
} fontmeasure_t;
} fonttextinfo_t;

View File

@ -40,111 +40,95 @@ void fontInit(font_t *font, char *data) {
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;
void fontDispose(font_t *font) {
textureDispose(&font->texture);
}
fontmeasure_t * fontTextMeasure(font_t *font, char *text, fonttextinfo_t *info,
float scale
) {
fonttextinfo_t * fontGetTextInfo(font_t *font, char *text, 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->width = 0, measure->height = 0;
measure->scale = scale;
measure->quads = malloc(sizeof(stbtt_aligned_quad) * info->realChars);
// Create info buffer.
fonttextinfo_t *info = malloc(sizeof(fonttextinfo_t));
info->length = 0;
info->realLength = 0;
// 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->realLength++;
}
// Now setup the size scales
info->quads = malloc(sizeof(stbtt_aligned_quad) * info->realLength);
info->scale = scale * FONT_SCALE_ADJUST;
info->width = 0, info->height = 0;
// Begin buffering quads.
x = 0;
y = FONT_INITIAL_LINE;
i = 0, j = 0;
while(c = text[i++]) {
// Spaces, don't quad just next
if(c == FONT_SPACE) {
x += info->spaceSize;
x += FONT_SPACE_SIZE;
continue;
}
// Newlines reset X
if(c == FONT_NEWLINE) {
y += info->lineHeight;
y += FONT_LINE_HEIGHT;
x = 0;
continue;
}
// Calculate the quad of the character, store into the array.
quad = measure->quads + j;
quad = info->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;
measure->width = mathMax(measure->width, quad->x1);
measure->height = mathMax(measure->height, quad->y1);
quad->x0 *= info->scale, quad->x1 *= info->scale;
quad->y0 *= info->scale, quad->y1 *= info->scale;
info->width = mathMax(info->width, quad->x1);
info->height = mathMax(info->height, quad->y1);
j++;
}
return measure;
return info;
}
void fontTextMeasureDispose(fontmeasure_t *measure) {
free(measure->quads);
free(measure);
void fontTextInfoDispose(fonttextinfo_t *info) {
free(info->quads);
free(info);
}
void fontDispose(font_t *font) {
textureDispose(&font->texture);
}
void fontTextBufferFromMeasure(font_t *font, primitive_t *primitive, char *text,
fontmeasure_t *measure
) {
void fontTextBuffer(font_t *font,primitive_t *primitive,fonttextinfo_t *info) {
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;
int32_t i;
for(i = 0; i < info->realLength; i++) {
quad = info->quads + i;
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
i*QUAD_VERTICE_COUNT, i*QUAD_INDICE_COUNT
);
j++;
}
}
void fontTextInitFromMeasure(font_t *font, primitive_t *primitive, char *text,
fonttextinfo_t *info, fontmeasure_t *measure
) {
void fontTextInit(font_t *font, primitive_t *primitive, fonttextinfo_t *info) {
primitiveInit(primitive,
QUAD_VERTICE_COUNT*info->realChars, QUAD_INDICE_COUNT*info->realChars
QUAD_VERTICE_COUNT * info->realLength, QUAD_INDICE_COUNT * info->realLength
);
fontTextBufferFromMeasure(font, primitive, text, measure);
fontTextBuffer(font, primitive, info);
}

View File

@ -20,31 +20,28 @@
void fontInit(font_t *font, char *data);
/**
* Generates information about how the given font will render the given text.
* @param font Font to get the information for.
* @param text Text that will be used to render
* @return Some information about how the font will render the text.
* Clean up a previously loaded font
* @param font Loaded font.
*/
fonttextinfo_t fontGetTextInfo(font_t *font, char *text);
void fontDispose(font_t *Font);
/**
* Measures (and calculates the quads for) a text prior to rendering it.
*
* @param font Font to use for rendering and measuring
* @param text Text to measure/render.
* @param info Info about the text being rendered / measured.
* @param scale Scale of the text.
* @returns Font measurement calculation.
* @returns Font info calculated.
*/
fontmeasure_t * fontTextMeasure(font_t *font, char *text, fonttextinfo_t *info,
float scale
);
fonttextinfo_t * fontGetTextInfo(font_t *font, char *text, float scale);
/**
* Disposes a previously calculated font text measurement.
* @param measure Measurement to dispose.
* Disposes a previously calculated font info struct..
* @param info Info to dispose.
*/
void fontTextMeasureDispose(fontmeasure_t *measure);
void fontTextInfoDispose(fonttextinfo_t *info);
/**
* Buffers the vertices of a font text onto a primitive. Requires some info
@ -52,28 +49,15 @@ void fontTextMeasureDispose(fontmeasure_t *measure);
*
* @param font Font to render.
* @param primitive Primitive to render into.
* @param text Text to render.
* @param measure The precalculated measurement.
* @param info The precalculated text info.
*/
void fontTextBufferFromMeasure(font_t *font, primitive_t *primitive, char *text,
fontmeasure_t *measure
);
void fontTextBuffer(font_t *font, primitive_t *primitive, fonttextinfo_t *info);
/**
* Initializes an uninitialized primitive for rendering.
*
* @param font Font to render.
* @param primitive Primitive to render into.
* @param text Text to render.
* @param info Text Info to use while rendering.
* @param measure The pre calcuted font measurement.
*/
void fontTextInitFromMeasure(font_t *font, primitive_t *primitive, char *text,
fonttextinfo_t *info, fontmeasure_t *measure
);
/**
* Clean up a previously loaded font
* @param font Loaded font.
*/
void fontDispose(font_t *Font);
void fontTextInit(font_t *font, primitive_t *primitive, fonttextinfo_t *info);

View File

@ -13,12 +13,10 @@ void pokerFrameInit(poker_t *poker, render_t *render) {
frameBufferInit(&poker->frameWorld, render->width, render->height);
frameBufferInit(&poker->frameGui, render->width, render->height);
fonttextinfo_t info;
fonttextinfo_t *info;
char *text = "Hello\n World";
info = fontGetTextInfo(&poker->font, text);
fontmeasure_t *measure = fontTextMeasure(&poker->font, text, &info, 16);
fontTextInitFromMeasure(&poker->font, &bruh, text, &info, measure);
fontTextMeasureDispose(measure);
info = fontGetTextInfo(&poker->font, text, 16);
fontTextInit(&poker->font, &bruh, info);
}
void pokerFrameWorld(poker_t *poker, render_t *render) {