summaryrefslogtreecommitdiff
path: root/text.c
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-11-20 22:28:38 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-11-20 22:28:38 -0500
commit5e458dff3bcc832b0b28d83bd3ef482174d1dc09 (patch)
tree28ac081edae5d36aad5df5b2e53848034dc2b99c /text.c
parentc3fd9dfa23969c842991da4cd852330288889463 (diff)
more text rendering
Diffstat (limited to 'text.c')
-rw-r--r--text.c82
1 files changed, 65 insertions, 17 deletions
diff --git a/text.c b/text.c
index 19d62a2..7007ad6 100644
--- a/text.c
+++ b/text.c
@@ -1,27 +1,25 @@
#include "base.h"
+#include "text.h"
+#define STB_TRUETYPE_IMPLEMENTATION
+#define STBTT_STATIC
no_warn_start
#include "stb_truetype.h"
no_warn_end
#include <stdarg.h>
#include <stdlib.h>
+#include <GL/gl.h>
-typedef struct {
+struct Font {
float char_height;
- u32 nchars;
GLuint texture;
+ u32 nchars;
stbtt_bakedchar chars[];
-} Font;
+};
static char text_err[200];
static void text_clear_err(void) {
text_err[0] = '\0';
}
-static void text_set_err(char const *fmt, ...) {
- va_list args;
- va_start(args, fmt);
- vsnprintf(text_err, sizeof text_err - 1, fmt, args);
- va_end(args);
-}
static bool text_has_err(void) {
return text_err[0] != '\0';
@@ -31,6 +29,15 @@ char const *text_get_err(void) {
return text_err;
}
+static void text_set_err(char const *fmt, ...) {
+ if (!text_has_err()) {
+ va_list args;
+ va_start(args, fmt);
+ vsnprintf(text_err, sizeof text_err - 1, fmt, args);
+ va_end(args);
+ }
+}
+
Font *text_font_load(char const *ttf_filename, float font_size) {
Font *font = NULL;
u32 nchars = 128;
@@ -42,30 +49,71 @@ Font *text_font_load(char const *ttf_filename, float font_size) {
fseek(ttf_file, 0, SEEK_END);
u32 file_size = (u32)ftell(ttf_file);
if (file_size < (50UL<<20)) { // fonts aren't usually bigger than 50 MB
- char *file_data = calloc(1, file_size);
- Font *font = calloc(1, sizeof *font + nchars * sizeof *font->chars);
+ u8 *file_data = calloc(1, file_size);
+ font = calloc(1, sizeof *font + nchars * sizeof *font->chars);
if (file_data && font) {
- font->nchars = nchars;
- font->char_height = font_size;
- stbtt_
+ if (fread(file_data, 1, file_size, ttf_file) == file_size) {
+ font->nchars = nchars;
+ font->char_height = font_size;
+
+ for (int bitmap_width = 256, bitmap_height = 256; bitmap_width <= 4096; bitmap_width *= 2, bitmap_height *= 2) {
+ u8 *bitmap = calloc((size_t)bitmap_width, (size_t)bitmap_height);
+ if (bitmap) {
+ int err = stbtt_BakeFontBitmap(file_data, 0, font->char_height, bitmap,
+ bitmap_width, bitmap_height, 0, (int)font->nchars, font->chars);
+ if (err > 0) {
+ // font converted to bitmap successfully.
+ GLuint texture = 0;
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, bitmap_width, bitmap_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ #if DEBUG
+ debug_println("Loaded font %s with %dx%d bitmap.", ttf_filename, bitmap_width, bitmap_height);
+ #endif
+ font->texture = texture;
+ if (glGetError()) {
+ text_set_err("Couldn't create texture for font.");
+ }
+ }
+ } else {
+ text_set_err("Not enough memory for font bitmap.");
+ }
+ free(bitmap);
+ if (font->texture) { // if font loaded successfully
+ break;
+ }
+ }
+ if (!font->texture && !text_has_err()) {
+ text_set_err("Couldn't convert font to bitmap.");
+ }
+ } else {
+ text_set_err("Couldn't read font file.", ttf_filename);
+ }
} else {
text_set_err("Not enough memory for font.");
}
free(file_data);
- if (text_has_err())
+ if (text_has_err()) {
free(font);
+ font = NULL;
+ }
fclose(ttf_file);
} else {
text_set_err("Font file too big (%u megabytes).", (uint)(file_size >> 20));
}
} else {
- text_set_err("Couldn't open font file: %s.", ttf_filename);
+ text_set_err("Couldn't open font file.", ttf_filename);
}
- return NULL;
+ return font;
}
+#if 0
void text_render(Font *font, char const *text, float x, float y) {
+
}
void text_get_size(Font *font, char const *text, float *width, float *height) {
}
+#endif