Added True Type fonts
This commit is contained in:
@ -8,13 +8,14 @@
|
||||
#include "camera.h"
|
||||
|
||||
void cameraLookAt(camera_t *camera,
|
||||
float x, float y, float z, float targetX, float targetY, float targetZ
|
||||
float x, float y, float z,
|
||||
float targetX, float targetY, float targetZ
|
||||
) {
|
||||
glm_mat4_identity(camera->view);
|
||||
glm_lookat(
|
||||
(vec3){ x, y, z },
|
||||
(vec3){ targetX, targetY, targetZ },
|
||||
(vec3){ 0, 1, 0 },
|
||||
(vec3){ 0,1,0 },
|
||||
camera->view
|
||||
);
|
||||
}
|
||||
@ -27,7 +28,7 @@ void cameraLook(camera_t *camera,
|
||||
glm_look(
|
||||
(vec3){ x, y, z },
|
||||
(vec3){ pitch, yaw, roll },
|
||||
(vec3){ 0, 1, 0 },
|
||||
(vec3){ 0,1,0 },
|
||||
camera->view
|
||||
);
|
||||
}
|
||||
|
@ -19,7 +19,8 @@
|
||||
* @param targetZ The Target Z position in world space of the camera.
|
||||
*/
|
||||
void cameraLookAt(camera_t *camera,
|
||||
float x, float y, float z, float targetX, float targetY, float targetZ
|
||||
float x, float y, float z,
|
||||
float targetX, float targetY, float targetZ
|
||||
);
|
||||
|
||||
/**
|
||||
|
116
src/display/gui/bitmapfont.c
Normal file
116
src/display/gui/bitmapfont.c
Normal file
@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "bitmapfont.h"
|
||||
|
||||
tilesetdiv_t * bitmapFontGetCharacterDivision(tileset_t *tileset, char character) {
|
||||
int32_t i = ((int32_t)character) - BITMAP_FONT_CHAR_START;
|
||||
return tileset->divisions + i;
|
||||
}
|
||||
|
||||
bitmapfontmeasure_t bitmapFontMeasure(char *string, float charWidth, float charHeight) {
|
||||
int32_t i;
|
||||
float x, y;
|
||||
char c;
|
||||
bitmapfontmeasure_t measure = {
|
||||
.height = 0, .lines = 1, .width = 0
|
||||
};
|
||||
|
||||
i = 0;
|
||||
y = 0;
|
||||
x = 0;
|
||||
|
||||
while(true) {
|
||||
c = string[i];
|
||||
if(c == '\0') break;
|
||||
i++;
|
||||
|
||||
if(c == '\n') {
|
||||
measure.width = mathMax(x, measure.width);
|
||||
x = 0;
|
||||
y += charHeight;
|
||||
measure.lines++;
|
||||
continue;
|
||||
} else if(c == ' ') {
|
||||
x += charWidth;
|
||||
continue;
|
||||
}
|
||||
|
||||
x += charWidth;
|
||||
}
|
||||
|
||||
measure.width = mathMax(x, measure.width);
|
||||
measure.height = y + charHeight;
|
||||
|
||||
return measure;
|
||||
}
|
||||
|
||||
bitmapfontmeasure_t bitmapFontSpriteBatchBuffer(
|
||||
spritebatch_t *batch, tileset_t *tileset,
|
||||
char *string, float x, float y, float z, float charWidth, float charHeight
|
||||
) {
|
||||
int32_t i;
|
||||
char c;
|
||||
tilesetdiv_t *div;
|
||||
float cx, cy;
|
||||
bitmapfontmeasure_t measure;
|
||||
|
||||
// Detect char dimensions
|
||||
if(charWidth == -1) charWidth = tileset->divX * (charHeight / tileset->divY);
|
||||
if(charHeight == -1) charHeight = tileset->divY * (charWidth / tileset->divX);
|
||||
|
||||
// Position the text.
|
||||
if(x == BITMAP_FONT_CENTER_X ||
|
||||
y == BITMAP_FONT_CENTER_Y ||
|
||||
x == BITMAP_FONT_RIGHT_X
|
||||
) {
|
||||
measure = bitmapFontMeasure(string, charWidth, charHeight);
|
||||
if(x == BITMAP_FONT_CENTER_X) {
|
||||
x = -(measure.width/2);
|
||||
} else if(x == BITMAP_FONT_RIGHT_X) {
|
||||
x = -measure.width;
|
||||
}
|
||||
if(y == BITMAP_FONT_CENTER_Y) y = -(measure.height/2);
|
||||
}
|
||||
|
||||
// Begin buffering the sprite batch
|
||||
measure.width = 0;
|
||||
measure.height = 0;
|
||||
measure.lines = 1;
|
||||
i = 0;
|
||||
cx = x, cy = y;
|
||||
|
||||
while(true) {
|
||||
c = string[i];
|
||||
if(c == '\0') break;
|
||||
i++;
|
||||
|
||||
// Special chars
|
||||
if(c == '\n') {
|
||||
measure.width = mathMax(cx-x, measure.width);
|
||||
cx = x;
|
||||
cy += charHeight;
|
||||
measure.lines++;
|
||||
continue;
|
||||
} else if(c == ' ') {
|
||||
cx += charWidth;
|
||||
continue;
|
||||
}
|
||||
|
||||
div = bitmapFontGetCharacterDivision(tileset, c);
|
||||
spriteBatchQuad(batch, -1,
|
||||
cx, cy, z, charWidth, charHeight,
|
||||
div->x0, div->y1, div->x1, div->y0
|
||||
);
|
||||
cx += charWidth;
|
||||
}
|
||||
|
||||
measure.width = mathMax(cx-x, measure.width);
|
||||
measure.height = cy-y + charHeight;
|
||||
|
||||
return measure;
|
||||
}
|
47
src/display/gui/bitmapfont.h
Normal file
47
src/display/gui/bitmapfont.h
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <dawn/dawn.h>
|
||||
#include "../spritebatch.h"
|
||||
|
||||
/**
|
||||
* Get the division for a given character.
|
||||
*
|
||||
* @param tileset Tileset to get the division from.
|
||||
* @param character Character to get the division for.
|
||||
* @return The division from the tileset for the character.
|
||||
*/
|
||||
tilesetdiv_t * bitmapFontGetCharacterDivision(tileset_t *tileset, char character);
|
||||
|
||||
/**
|
||||
* Measures a string's fully rendered size.
|
||||
*
|
||||
* @param string The string to measure
|
||||
* @param charWidth The width of each character.
|
||||
* @param charHeight The height of each character.
|
||||
* @return The measured string.
|
||||
*/
|
||||
bitmapfontmeasure_t bitmapFontMeasure(char *string, float charWidth, float charHeight);
|
||||
|
||||
/**
|
||||
* Renders a set of font characters to the sprite. Coordinates are anchored to
|
||||
* the top left (0,0) origin.
|
||||
*
|
||||
* @param batch Sprite Batch to render to.
|
||||
* @param tileset Tileset for the font.
|
||||
* @param string String to render.
|
||||
* @param x Position in X space.
|
||||
* @param y Position in Y space.
|
||||
* @param z Position in Z space.
|
||||
* @param charWidth Width of each character. Set to -1 to use the height ratio.
|
||||
* @param charHeight Height of each character. Set to -1 to be the width ratio.
|
||||
* @returns The string measurement.
|
||||
*/
|
||||
bitmapfontmeasure_t bitmapFontSpriteBatchBuffer(spritebatch_t *batch, tileset_t *tileset,
|
||||
char *string, float x, float y, float z, float charWidth, float charHeight
|
||||
);
|
@ -7,109 +7,137 @@
|
||||
|
||||
#include "font.h"
|
||||
|
||||
tilesetdiv_t * fontGetCharacterDivision(tileset_t *tileset, char character) {
|
||||
int32_t i = ((int32_t)character) - FONT_CHAR_START;
|
||||
return tileset->divisions + i;
|
||||
// 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, float size) {
|
||||
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);
|
||||
|
||||
font->size = size;
|
||||
|
||||
// STBTT Loads fonts as single channel values only.
|
||||
stbtt_BakeFontBitmap(
|
||||
data, 0, 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);
|
||||
}
|
||||
|
||||
fontmeasure_t fontMeasure(char *string, float charWidth, float charHeight) {
|
||||
int32_t i;
|
||||
fonttextinfo_t fontGetTextInfo(font_t *font, char *text) {
|
||||
float x, y;
|
||||
char c;
|
||||
fontmeasure_t measure = {
|
||||
.height = 0, .lines = 1, .width = 0
|
||||
int32_t i;
|
||||
fonttextinfo_t info = {
|
||||
.length = 0,
|
||||
.realChars = 0,
|
||||
.lineHeight = FONT_LINE_HEIGHT * font->size,
|
||||
.spaceSize = font->size * FONT_SPACE_SIZE
|
||||
};
|
||||
|
||||
// Count how many "real characters" are in the string.
|
||||
i = 0;
|
||||
y = 0;
|
||||
x = 0;
|
||||
while(c = text[i++]) {
|
||||
info.length++;
|
||||
if(c == FONT_SPACE) continue;
|
||||
if(c == FONT_NEWLINE) continue;
|
||||
info.realChars++;
|
||||
}
|
||||
|
||||
while(true) {
|
||||
c = string[i];
|
||||
if(c == '\0') break;
|
||||
i++;
|
||||
|
||||
if(c == '\n') {
|
||||
measure.width = mathMax(x, measure.width);
|
||||
x = 0;
|
||||
y += charHeight;
|
||||
measure.lines++;
|
||||
continue;
|
||||
} else if(c == ' ') {
|
||||
x += charWidth;
|
||||
return info;
|
||||
}
|
||||
|
||||
fontmeasure_t * fontTextMeasure(font_t *font,char *text,fonttextinfo_t *info) {
|
||||
int32_t i, j;
|
||||
char c;
|
||||
float x, y;
|
||||
stbtt_aligned_quad *quad;
|
||||
fontmeasure_t *measure;
|
||||
|
||||
measure = malloc(sizeof(fontmeasure_t));
|
||||
measure->quads = malloc(sizeof(stbtt_aligned_quad) * info->realChars);
|
||||
|
||||
x = 0;
|
||||
y = FONT_INITIAL_LINE * font->size;
|
||||
|
||||
i = 0, j = 0;
|
||||
while(c = text[i++]) {
|
||||
if(c == FONT_SPACE) {
|
||||
x += info->spaceSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
x += charWidth;
|
||||
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
|
||||
);
|
||||
j++;
|
||||
}
|
||||
|
||||
measure.width = mathMax(x, measure.width);
|
||||
measure.height = y + charHeight;
|
||||
|
||||
return measure;
|
||||
}
|
||||
|
||||
fontmeasure_t fontSpriteBatchBuffer(spritebatch_t *batch, tileset_t *tileset,
|
||||
char *string, float x, float y, float z, float charWidth, float charHeight
|
||||
void fontTextMeasureDispose(fontmeasure_t *measure) {
|
||||
free(measure->quads);
|
||||
free(measure);
|
||||
}
|
||||
|
||||
void fontTextBufferFromMeasure(font_t *font, primitive_t *primitive, char *text,
|
||||
fontmeasure_t *measure
|
||||
) {
|
||||
int32_t i;
|
||||
stbtt_aligned_quad *quad;
|
||||
int32_t i, j;
|
||||
char c;
|
||||
tilesetdiv_t *div;
|
||||
float cx, cy;
|
||||
fontmeasure_t measure;
|
||||
|
||||
// Detect char dimensions
|
||||
if(charWidth == -1) charWidth = tileset->divX * (charHeight / tileset->divY);
|
||||
if(charHeight == -1) charHeight = tileset->divY * (charWidth / tileset->divX);
|
||||
|
||||
// Position the text.
|
||||
if(x == FONT_CENTER_X ||
|
||||
y == FONT_CENTER_Y ||
|
||||
x == FONT_RIGHT_X
|
||||
) {
|
||||
measure = fontMeasure(string, charWidth, charHeight);
|
||||
if(x == FONT_CENTER_X) {
|
||||
x = -(measure.width/2);
|
||||
} else if(x == FONT_RIGHT_X) {
|
||||
x = -measure.width;
|
||||
}
|
||||
if(y == FONT_CENTER_Y) y = -(measure.height/2);
|
||||
}
|
||||
|
||||
// Begin buffering the sprite batch
|
||||
measure.width = 0;
|
||||
measure.height = 0;
|
||||
measure.lines = 1;
|
||||
i = 0;
|
||||
cx = x, cy = y;
|
||||
|
||||
while(true) {
|
||||
c = string[i];
|
||||
if(c == '\0') break;
|
||||
i++;
|
||||
|
||||
// Special chars
|
||||
if(c == '\n') {
|
||||
measure.width = mathMax(cx-x, measure.width);
|
||||
cx = x;
|
||||
cy += charHeight;
|
||||
measure.lines++;
|
||||
continue;
|
||||
} else if(c == ' ') {
|
||||
cx += charWidth;
|
||||
continue;
|
||||
}
|
||||
|
||||
div = fontGetCharacterDivision(tileset, c);
|
||||
spriteBatchQuad(batch, -1,
|
||||
cx, cy, z, charWidth, charHeight,
|
||||
div->x0, div->y1, div->x1, div->y0
|
||||
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
|
||||
);
|
||||
cx += charWidth;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
measure.width = mathMax(cx-x, measure.width);
|
||||
measure.height = cy-y + charHeight;
|
||||
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);
|
||||
}
|
||||
|
||||
return measure;
|
||||
void fontDispose(font_t *font) {
|
||||
textureDispose(&font->texture);
|
||||
}
|
@ -6,42 +6,72 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <dawn/dawn.h>
|
||||
#include "../spritebatch.h"
|
||||
#include "../texture.h"
|
||||
#include "../primitive.h"
|
||||
#include "../primitives/quad.h"
|
||||
|
||||
/**
|
||||
* Get the division for a given character.
|
||||
*
|
||||
* @param tileset Tileset to get the division from.
|
||||
* @param character Character to get the division for.
|
||||
* @return The division from the tileset for the character.
|
||||
* Initializes Font from raw TTF data.
|
||||
* @param font Font to initialize
|
||||
* @param data Data to intialize for.
|
||||
* @param size Font size to load the font in.
|
||||
*/
|
||||
tilesetdiv_t * fontGetCharacterDivision(tileset_t *tileset, char character);
|
||||
void fontInit(font_t *font, char *data, float size);
|
||||
|
||||
/**
|
||||
* Measures a string's fully rendered size.
|
||||
*
|
||||
* @param string The string to measure
|
||||
* @param charWidth The width of each character.
|
||||
* @param charHeight The height of each character.
|
||||
* @return The measured string.
|
||||
* 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.
|
||||
*/
|
||||
fontmeasure_t fontMeasure(char *string, float charWidth, float charHeight);
|
||||
fonttextinfo_t fontGetTextInfo(font_t *font, char *text);
|
||||
|
||||
/**
|
||||
* Renders a set of font characters to the sprite. Coordinates are anchored to
|
||||
* the top left (0,0) origin.
|
||||
* Measures (and calculates the quads for) a text prior to rendering it.
|
||||
*
|
||||
* @param batch Sprite Batch to render to.
|
||||
* @param tileset Tileset for the font.
|
||||
* @param string String to render.
|
||||
* @param x Position in X space.
|
||||
* @param y Position in Y space.
|
||||
* @param z Position in Z space.
|
||||
* @param charWidth Width of each character. Set to -1 to use the height ratio.
|
||||
* @param charHeight Height of each character. Set to -1 to be the width ratio.
|
||||
* @returns The string measurement.
|
||||
* @param font Font to use for rendering and measuring
|
||||
* @param text Text to measure/render.
|
||||
* @param info Info about the text being rendered / measured.
|
||||
* @returns Font measurement calculation.
|
||||
*/
|
||||
fontmeasure_t fontSpriteBatchBuffer(spritebatch_t *batch, tileset_t *tileset,
|
||||
char *string, float x, float y, float z, float charWidth, float charHeight
|
||||
);
|
||||
fontmeasure_t * fontTextMeasure(font_t *font, char *text, fonttextinfo_t *info);
|
||||
|
||||
/**
|
||||
* Disposes a previously calculated font text measurement.
|
||||
* @param measure Measurement to dispose.
|
||||
*/
|
||||
void fontTextMeasureDispose(fontmeasure_t *measure);
|
||||
|
||||
/**
|
||||
* Buffers the vertices of a font text onto a primitive. Requires some info
|
||||
* about how the font is meant to render from the text info section.
|
||||
*
|
||||
* @param font Font to render.
|
||||
* @param primitive Primitive to render into.
|
||||
* @param text Text to render.
|
||||
* @param measure The precalculated measurement.
|
||||
*/
|
||||
void fontTextBufferFromMeasure(font_t *font, primitive_t *primitive, char *text,
|
||||
fontmeasure_t *measure
|
||||
);
|
||||
|
||||
/**
|
||||
* 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);
|
@ -7,6 +7,12 @@
|
||||
|
||||
#include "texture.h"
|
||||
|
||||
// Due to some compiler bullshit, this is here.
|
||||
#ifndef STB_IMAGE_IMPLEMENTATION
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
#endif
|
||||
|
||||
void textureInit(texture_t *texture, int32_t width, int32_t height,
|
||||
pixel_t *pixels
|
||||
) {
|
||||
|
Reference in New Issue
Block a user