aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKrow Savcik <krow@savcik.xyz>2024-02-13 18:31:38 +0200
committerKrow Savcik <krow@savcik.xyz>2024-02-13 18:31:38 +0200
commit306691b02acce8711ad82c8efc736164e1fe7cd2 (patch)
treebbe81b65cf1b07e6a5c0ca1d870a33612c87f66a /src
parent669f50e2d6fc55751e0f3afb4d1bdf633446b169 (diff)
feature: simple text rendering ability
Diffstat (limited to 'src')
-rw-r--r--src/cdraw.c16
-rw-r--r--src/cdraw.h1
-rw-r--r--src/sbdf.h214
3 files changed, 230 insertions, 1 deletions
diff --git a/src/cdraw.c b/src/cdraw.c
index ecec5de..6088df9 100644
--- a/src/cdraw.c
+++ b/src/cdraw.c
@@ -1,12 +1,18 @@
#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
+#define SBDF_IMPLEMENTATION
+#define SBDF_USESDL
+#include "sbdf.h"
#include "cdraw.h"
#include "types.h"
+#include "debug.h"
#include "action.h"
#include "canvas.h"
-#include "debug.h"
#include "palette.h"
#include "ui.h"
@@ -21,6 +27,7 @@ typedef struct {
SDL_Window *win;
void *ren;
+void *font;
void *def_palette;
struct Canvas* cur_canvas;
@@ -50,12 +57,15 @@ main_quit()
SDL_DestroyWindow(win);
IMG_Quit();
SDL_Quit();
+ SBDF_FontDestroy(font);
+ font = NULL;
return 1;
}
uint
main_window_init(const char *s)
{
+ /* TODO: defer*/
int ss;
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("SDL_Init failed: %s\n", SDL_GetError());
@@ -88,6 +98,10 @@ main_window_init(const char *s)
if (def_palette == NULL)
return 1;
+ font = SBDF_FontLoad(def_font);
+ if (font == NULL)
+ return 1;
+
ui_create(def_theme_path);
if (s == NULL)
cur_canvas = canvas_init(64, 64, ren);
diff --git a/src/cdraw.h b/src/cdraw.h
index 633eea7..e3bc4fd 100644
--- a/src/cdraw.h
+++ b/src/cdraw.h
@@ -8,6 +8,7 @@ typedef union {
extern SDL_Window *win;
extern void *ren;
+extern void *font;
extern void *def_palette;
extern const char *def_palette_path;
extern const char *cmd_file_picker;
diff --git a/src/sbdf.h b/src/sbdf.h
new file mode 100644
index 0000000..ba6d413
--- /dev/null
+++ b/src/sbdf.h
@@ -0,0 +1,214 @@
+/*
+ BDF simple reader and printer (ASCII Support only)
+ include stdio.h stddef.h stdlib.h string.h
+ Should define SBDF_IMPLEMENTATION in only one .c file
+*/
+
+typedef struct SBDF_Font SBDF_Font;
+
+SBDF_Font* SBDF_FontLoad(const char *);
+void SBDF_FontDestroy(SBDF_Font *);
+#ifdef SBDF_USESDL
+void SBDF_SDLPrint(const SDL_Renderer *, const SBDF_Font *, const char *, int, int);
+#endif
+
+#ifdef SBDF_IMPLEMENTATION
+struct SBDF_Glyph {
+ int dx, dy;
+ int bx, by, bw, bh;
+ size_t s;
+};
+
+struct SBDF_Font {
+ struct SBDF_Glyph g[256];
+ unsigned char *data;
+};
+
+struct SBDF_Font*
+SBDF_FontInit(size_t sz) {
+ struct SBDF_Font *res;
+ int i;
+ res = malloc(sizeof(*res));
+ if (res == NULL) return NULL;
+
+ res->data = malloc(sz);
+ if (res->data == NULL) {
+ free(res);
+ return NULL;
+ }
+ for (i = 0; i < 256; i++)
+ res->g[i].s = -1;
+ return res;
+}
+
+void
+SBDF_FontDestroy(struct SBDF_Font *f) {
+ if (f == NULL) return;
+ free(f->data);
+ free(f);
+}
+
+#define SBDF_NULL 0x00000
+#define SBDF_PROPS 0x00010
+#define SBDF_CHARS 0x00100
+#define SBDF_GLYPH 0x01100
+
+struct SBDF_Font*
+SBDF_FontLoad(const char *path) {
+ FILE *f;
+ int cnt, rd, tp;
+ struct SBDF_Glyph g;
+ size_t sz;
+ char line[2049];
+ char word[2049];
+ char *v;
+ unsigned char val;
+ int state;
+ struct SBDF_Font *res;
+ res = NULL;
+ f = fopen(path, "r");
+ if (f == NULL) goto SBDF_FontLoad_defer;
+
+ state = SBDF_NULL;
+ rd = cnt = sz = 0;
+ while (fgets(line, 2049, f)) {
+ if ((state&SBDF_CHARS) == 0) {
+ sscanf(line, "%s", word);
+ if (state == SBDF_PROPS) {
+ if (strcmp(word, "ENDPROPERTIES") == 0)
+ state = SBDF_NULL;
+ } else {
+ if (strcmp(word, "STARTPROPERTIES") == 0)
+ state = SBDF_PROPS;
+ else if (strcmp(word, "CHARS") == 0)
+ state = SBDF_CHARS;
+ }
+ continue;
+ } else {
+ sscanf(line, "%s", word);
+ if (cnt) {
+ --cnt;
+ continue;
+ }
+ if (strcmp(word, "ENCODING") == 0) {
+ sscanf(line, "%*s %d", &tp);
+ rd = (tp > -1 && tp < 256);
+ continue;
+ }
+ if (strcmp(word, "DWIDTH") == 0) {
+ sscanf(line, "%*s %d %d", &g.dx, &g.dy);
+ continue;
+ }
+ if (strcmp(word, "BBX") == 0) {
+ sscanf(line, "%*s %d %d %d %d", &g.bw, &g.bh, &g.bx, &g.by);
+ if (rd) {
+ sz += (g.bw+7) / 8 * g.bh;
+ }
+ continue;
+ }
+ if (strcmp(word, "BITMAP") == 0) {
+ cnt = g.bh;
+ continue;
+ }
+ }
+ }
+
+ fclose(f);
+ res = SBDF_FontInit(sz);
+ if (res == NULL) goto SBDF_FontLoad_defer;
+ f = fopen(path, "r");
+ if (f == NULL) goto SBDF_FontLoad_defer;
+
+ state = SBDF_NULL;
+ rd = cnt = sz = 0;
+ while (fgets(line, 2049, f)) {
+ if ((state&SBDF_CHARS) == 0) {
+ sscanf(line, "%s", word);
+ if (state == SBDF_PROPS) {
+ if (strcmp(word, "ENDPROPERTIES") == 0)
+ state = SBDF_NULL;
+ } else {
+ if (strcmp(word, "STARTPROPERTIES") == 0)
+ state = SBDF_PROPS;
+ else if (strcmp(word, "CHARS") == 0)
+ state = SBDF_CHARS;
+ }
+ continue;
+ } else {
+ sscanf(line, "%s", word);
+ if (cnt) {
+ --cnt;
+ if (rd) {
+ v = word;
+ while (v[0] != '\0') {
+ if (v[0] <= '9')
+ val = (unsigned char)16*(v[0] - '0');
+ else
+ val = (unsigned char)16*(v[0] - 'A' + 10);
+ if (v[1] <= '9')
+ val += (unsigned char)(v[1] - '0');
+ else
+ val += (unsigned char)(v[1] - 'A' + 10);
+ res->data[sz] = val;
+ sz++;
+ v += 2;
+ }
+ }
+ continue;
+ }
+ if (strcmp(word, "ENCODING") == 0) {
+ sscanf(line, "%*s %d", &tp);
+ rd = (tp > -1 && tp < 256);
+ continue;
+ }
+ if (strcmp(word, "DWIDTH") == 0) {
+ sscanf(line, "%*s %d %d", &g.dx, &g.dy);
+ continue;
+ }
+ if (strcmp(word, "BBX") == 0) {
+ sscanf(line, "%*s %d %d %d %d", &g.bw, &g.bh, &g.bx, &g.by);
+ continue;
+ }
+ if (strcmp(word, "BITMAP") == 0) {
+ cnt = g.bh;
+ if (rd) {
+ g.s = sz;
+ res->g[tp] = g;
+ }
+ continue;
+ }
+ }
+ }
+ return res;
+SBDF_FontLoad_defer:
+ if (f != NULL)
+ fclose(f);
+ SBDF_FontDestroy(res);
+ return NULL;
+}
+
+#ifdef SBDF_USESDL
+void
+SBDF_SDLPrint(const SDL_Renderer *r, const struct SBDF_Font *f, const char *text, int x, int y) {
+ char *u;
+ unsigned char *v;
+ int i, j;
+ u = text;
+ while (*u != '\0') {
+ v = &f->data[f->g[*u].s];
+ x += f->g[*u].bx;
+ y += f->g[*u].by;
+ for (i = 0; i < f->g[*u].bh; i++) {
+ for (j = 0; j < f->g[*u].bw; j++) {
+ if (v[j/8]>>(7-(j%8))&1)
+ SDL_RenderDrawPoint(r, x+j, y+i);
+ }
+ v += (j + 7) / 8;
+ }
+ x += f->g[*u].dx - f->g[*u].bx;
+ y += f->g[*u].dy - f->g[*u].by;
+ u++;
+ }
+}
+#endif
+#endif