summaryrefslogtreecommitdiff
path: root/font.c
diff options
context:
space:
mode:
authorcflip <cflip@cflip.net>2023-01-08 21:25:21 -0700
committercflip <cflip@cflip.net>2023-01-08 21:25:21 -0700
commitc2e8836f592db9cf28111182ea40f1268c758933 (patch)
tree1dce79a44616787778a0223eb4e4dcfccf7f2e83 /font.c
parent76010f7b97e6b71db6e123d28c91f997ff56945c (diff)
Connect the window and font code to the editor's main function
Diffstat (limited to 'font.c')
-rw-r--r--font.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/font.c b/font.c
new file mode 100644
index 0000000..00b7f4d
--- /dev/null
+++ b/font.c
@@ -0,0 +1,137 @@
+#include "font.h"
+
+/* Create a texture containing all of the glyphs in a specified BDF file. */
+SDL_Texture *font_create_texture(SDL_Renderer *renderer, BDFFontInfo *font)
+{
+ SDL_Texture *result;
+ SDL_Surface *surface = SDL_CreateRGBSurface(0, 8 * font->num_chars, font->bounds.h, 32, 0, 0, 0, 0);
+
+ printf("Made surface of size %dx%d\n", surface->w, surface->h);
+ SDL_LockSurface(surface);
+ for (int i = 0; i < font->num_chars; i++) {
+ BDFFontChar chair = font->chars[i];
+ for (int y = 0; y < font->bounds.h; y++) {
+ int bits_for_row = chair.bitmap[y];
+ for (int x = 0; x < 8; x++) {
+ int bit_index = 7 - x;
+ int current_bit = bits_for_row & (1 << bit_index);
+ int xp = x + i * 8;
+ int yp = y;
+ ((Uint32*)(surface->pixels))[xp + yp * surface->w] = current_bit ? 0xffffffff : 0;
+ }
+ }
+ }
+ SDL_UnlockSurface(surface);
+
+ result = SDL_CreateTextureFromSurface(renderer, surface);
+ if (result == NULL) {
+ fprintf(stderr, "Failed to create texture: %s\n", SDL_GetError());
+ }
+ SDL_FreeSurface(surface);
+ return result;
+}
+
+/*
+ * Loads a BDF font file into a data structure.
+ * TODO: This is extremely atrocious!
+ */
+BDFFontInfo font_load(const char *filename)
+{
+ FILE *fp;
+ char *line = NULL;
+ size_t len = 0;
+ ssize_t bytes_read;
+
+ BDFFontInfo result;
+ result.bounds.x = 0;
+ result.bounds.y = 0;
+ result.bounds.w = 0;
+ result.bounds.h = 0;
+ result.chars = NULL;
+ result.num_chars = 0;
+
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+ fprintf(stderr, "Failed to open file from %s\n", filename);
+ return;
+ }
+
+ int is_reading_bitmap = 0;
+ int char_counter = -1;
+ while ((bytes_read = getline(&line, &len, fp)) != -1) {
+ if (strncmp(line, "FONTBOUNDINGBOX", 15) == 0) {
+ sscanf(line, "FONTBOUNDINGBOX %d %d %d %d\n", &result.bounds.w,
+ &result.bounds.h,
+ &result.bounds.x,
+ &result.bounds.y);
+
+ }
+
+ if (strncmp(line, "CHARS", 5) == 0) {
+ sscanf(line, "CHARS %d\n", &result.num_chars);
+ result.chars = malloc(result.num_chars * sizeof(BDFFontChar));
+ }
+
+ if (strncmp(line, "STARTCHAR", 9) == 0) {
+ char_counter++;
+ result.chars[char_counter].code_point = 0;
+ result.chars[char_counter].next_glyph_offset.x = 0;
+ result.chars[char_counter].next_glyph_offset.y = 0;
+ result.chars[char_counter].bounds.x = 0;
+ result.chars[char_counter].bounds.y = 0;
+ result.chars[char_counter].bounds.w = 0;
+ result.chars[char_counter].bounds.h = 0;
+ result.chars[char_counter].bitmap = NULL;
+ result.chars[char_counter].bitmap_size = 0;
+ }
+
+ if (strncmp(line, "ENCODING", 8) == 0) {
+ int code_point = 0;
+ sscanf(line, "ENCODING %d\n", &code_point);
+ if (code_point < 256)
+ result.char_index_for_code_point[code_point] = char_counter;
+ result.chars[char_counter].code_point = code_point;
+ }
+
+ if (strncmp(line, "DWIDTH", 6) == 0) {
+ sscanf(line, "DWIDTH %d %d\n", &result.chars[char_counter].next_glyph_offset.x,
+ &result.chars[char_counter].next_glyph_offset.y);
+ }
+
+ if (strncmp(line, "BBX", 3) == 0) {
+ sscanf(line, "BBX %d %d %d %d\n", &result.chars[char_counter].bounds.w,
+ &result.chars[char_counter].bounds.h,
+ &result.chars[char_counter].bounds.x,
+ &result.chars[char_counter].bounds.y);
+ result.chars[char_counter].bounds.x += char_counter * 8;
+ result.chars[char_counter].bounds.y = -result.chars[char_counter].bounds.y;
+ }
+
+ if (strncmp(line, "BITMAP", 6) == 0) {
+ is_reading_bitmap = 1;
+ }
+
+ if (is_reading_bitmap) {
+ if (strncmp(line, "ENDCHAR", 7) == 0) {
+ is_reading_bitmap = 0;
+ continue;
+ }
+
+ BDFFontChar *chair = &result.chars[char_counter];
+ chair->bitmap = realloc(chair->bitmap, chair->bitmap_size++);
+ chair->bitmap[chair->bitmap_size - 1] = strtol(line, NULL, 16);
+ }
+ }
+
+ fclose(fp);
+ if (line) { free(line); }
+
+ return result;
+}
+
+void font_destroy(BDFFontInfo *font)
+{
+ for (int i = 0; i < font->num_chars; i++)
+ free(font->chars[i].bitmap);
+ free(font->chars);
+}