summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--assets/font.ttfbin0 -> 107848 bytes
-rw-r--r--base.h22
-rw-r--r--main.c5
-rw-r--r--text.c82
5 files changed, 95 insertions, 20 deletions
diff --git a/Makefile b/Makefile
index 42064a0..e10bdc9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
ALL_CFLAGS=$(CFLAGS) -Wall -Wextra -Wshadow -Wconversion -Wpedantic -pedantic -std=gnu11 \
-Wno-unused-function -Wno-fixed-enum-extension -Wimplicit-fallthrough
-LIBS=-lSDL2 -lGL -ldl
-DEBUG_CFLAGS=$(ALL_CFLAGS) $(LIBS) -DDEBUG -O0 -g
+LIBS=-lSDL2 -lGL -ldl -lm
+DEBUG_CFLAGS=$(ALL_CFLAGS) -DDEBUG -O0 -g
ted: *.[ch] text.o
- $(CC) main.c text.o -o $@ $(DEBUG_CFLAGS)
+ $(CC) main.c text.o -o $@ $(DEBUG_CFLAGS) $(LIBS)
%.o: %.c
$(CC) $< -c -o $@ $(DEBUG_CFLAGS)
diff --git a/assets/font.ttf b/assets/font.ttf
new file mode 100644
index 0000000..3560a3a
--- /dev/null
+++ b/assets/font.ttf
Binary files differ
diff --git a/base.h b/base.h
index 92270bc..8327fdb 100644
--- a/base.h
+++ b/base.h
@@ -1,6 +1,10 @@
#ifndef BASE_H_
#define BASE_H_
+#ifndef DEBUG
+#define NDEBUG 1
+#endif
+
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
@@ -34,4 +38,22 @@ typedef unsigned long ulong;
#define no_warn_end
#endif
+#if DEBUG
+#if __unix__
+#define debug_println printf
+#else // __unix__
+static void debug_println(char const *fmt, ...) {
+ char buf[256];
+ va_list args;
+ va_start(args, fmt);
+ vsprintf_s(buf, sizeof buf, fmt, args);
+ va_end(args);
+ OutputDebugStringA(buf);
+ OutputDebugStringA("\n");
+}
+#endif // __unix__
+#else // DEBUG
+#define debug_println(...)
+#endif
+
#endif
diff --git a/main.c b/main.c
index 1d549a6..2353d08 100644
--- a/main.c
+++ b/main.c
@@ -3,6 +3,7 @@ no_warn_start
#include <SDL2/SDL.h>
no_warn_end
#include <GL/gl.h>
+#include "text.h"
static void die(char const *fmt, ...) {
char buf[256] = {0};
@@ -38,6 +39,10 @@ int main(void) {
SDL_GL_SetSwapInterval(1); // vsync
+ Font *font = text_font_load("assets/font.ttf", 12);
+ if (!font) {
+ die("Couldn't load font: %s", text_get_err());
+ }
bool quit = false;
while (!quit) {
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