Commit: 7041d1c39b7230d118a70270536b218fc5ba67c4
Parent: 22cc7c97755d177b070650ec2e9781a05ba81d11
Author: Randy Palamar
Date: Sun, 18 Aug 2024 13:35:29 -0600
use fontconfig to find fonts
Diffstat:
5 files changed, 68 insertions(+), 32 deletions(-)
diff --git a/build.sh b/build.sh
@@ -1,9 +1,9 @@
#!/bin/sh
cflags="-march=native -ggdb -O0 -Wall"
-cflags="$cflags $(pkg-config --cflags glfw3 gl freetype2)"
+cflags="$cflags $(pkg-config --cflags glfw3 gl fontconfig)"
ldflags=""
-ldflags="$ldflags -lfreetype $(pkg-config --static --libs glfw3 gl)"
+ldflags="$ldflags $(pkg-config --static --libs glfw3 gl fontconfig)"
# Hot Reloading/Debugging
cflags="$cflags -D_DEBUG -Wno-unused-function -Wno-undefined-internal"
diff --git a/config.def.h b/config.def.h
@@ -2,6 +2,9 @@
static s8 g_default_title = s8("vtgl");
static u32 g_default_fontsize = 36;
+static char *g_fonts[] = {
+ "monospace:style=Regular",
+};
static u8 g_tabstop = 8;
diff --git a/font.c b/font.c
@@ -1,28 +1,50 @@
/* See LICENSE for copyright details */
-static void
-init_font(FT_Library *ftlib, Font *f, char *path, u32 fontsize)
+static b32
+init_font(FontAtlas *fa, Font *f, u8 *fontstr, u32 fontsize)
{
- if (!*ftlib && FT_Init_FreeType(ftlib))
- die("Failed to init FreeType\n");
+ f->pattern = FcNameParse(fontstr);
+ if (!f->pattern) {
+ fprintf(stderr, "init_font: failed to parse font name to pattern: %s\n", fontstr);
+ return 0;
+ }
+ FcConfigSubstitute(fa->fc, f->pattern, FcMatchPattern);
+ FcDefaultSubstitute(f->pattern);
+
+ FcResult res;
+ FcPattern *font = FcFontMatch(fa->fc, f->pattern, &res);
+ if (!font)
+ goto err_fc1;
- os_mapped_file map = os_map_file(path, OS_MAP_READ, OS_MAP_PRIVATE);
+ u8 *file = 0;
+ if (!(FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch))
+ goto err_fc2;
+
+ os_mapped_file map = os_map_file((char *)file, OS_MAP_READ, OS_MAP_PRIVATE);
f->bufsize = map.len;
f->buf = map.data;
- if (FT_New_Memory_Face(*ftlib, f->buf, f->bufsize, 0, &f->face))
- goto err1;
+ if (FT_New_Memory_Face(fa->ftlib, f->buf, f->bufsize, 0, &f->face))
+ goto err_ft1;
if (FT_Set_Pixel_Sizes(f->face, 0, fontsize))
- goto err2;
+ goto err_ft2;
if (FT_Select_Charmap(f->face, FT_ENCODING_UNICODE))
- goto err2;
+ goto err_ft2;
+
+ FcPatternDestroy(font);
- return;
-err2:
+ return 1;
+
+err_ft2:
FT_Done_Face(f->face);
-err1:
+err_ft1:
os_unmap_file(f->buf, f->bufsize);
- die("Failed to init font: %s\n", path);
+err_fc2:
+ FcPatternDestroy(font);
+err_fc1:
+ FcPatternDestroy(f->pattern);
+ f->pattern = NULL;
+ return 0;
}
static u8 *
@@ -80,11 +102,23 @@ set_font_sizes(FontAtlas *fa, u32 fontsize)
}
static void
-init_fonts(Term *t, char **paths, u32 npaths, u32 fontsize, Arena *a)
+init_fonts(Term *t, char **fontstrs, u32 nfontstrs, u32 fontsize, Arena *a)
{
- t->fa.fonts = alloc(a, Font, npaths);
- for (t->fa.nfonts = 0; t->fa.nfonts < npaths; t->fa.nfonts++)
- init_font(&t->ftlib, t->fa.fonts + t->fa.nfonts, paths[t->fa.nfonts], fontsize);
+ if (FT_Init_FreeType(&t->fa.ftlib))
+ die("init_fonts: failed to init FreeType\n");
+ if (!(t->fa.fc = FcInitLoadConfigAndFonts()))
+ die("init_fonts: failed to init FontConfig\n");
+
+ b32 valid_atlas = 0;
+ t->fa.fonts = alloc(a, Font, nfontstrs);
+ for (t->fa.nfonts = 0; t->fa.nfonts < nfontstrs; t->fa.nfonts++) {
+ valid_atlas |= init_font(&t->fa, t->fa.fonts + t->fa.nfonts,
+ (u8 *)fontstrs[t->fa.nfonts], fontsize);
+ }
+ if (!valid_atlas) {
+ /* TODO: open some default font */
+ die("init_fonts: no valid font patterns\n");
+ }
t->gl.glyph_cache_len = 0x7E - 0x20 + 1;
t->gl.glyph_cache = alloc(a, Glyph, t->gl.glyph_cache_len);
diff --git a/main.c b/main.c
@@ -272,11 +272,8 @@ main(void)
Arena memory = os_new_arena(16 * MEGABYTE);
Term term = {0};
- static char *font_paths[] = {
- "/usr/share/fonts/gofont/Go-Mono.ttf",
- };
init_window(&term, memory);
- init_fonts(&term, font_paths, ARRAY_COUNT(font_paths), g_default_fontsize, &memory);
+ init_fonts(&term, g_fonts, ARRAY_COUNT(g_fonts), g_default_fontsize, &memory);
for (u32 i = 0; i < ARRAY_COUNT(term.saved_cursors); i++) {
cursor_reset(&term);
diff --git a/util.h b/util.h
@@ -242,6 +242,7 @@ typedef struct {
#include <ft2build.h>
#include FT_FREETYPE_H
+#include <fontconfig/fontconfig.h>
#include "util.c"
#ifdef __unix__
@@ -251,16 +252,19 @@ typedef struct {
#endif
typedef struct {
- u8 *buf;
- i32 bufsize;
- FT_Face face;
+ u8 *buf;
+ i32 bufsize;
+ FcPattern *pattern;
+ FT_Face face;
} Font;
typedef struct {
- Font *fonts;
- u32 nfonts;
- uv2 size;
- i32 deltay;
+ FT_Library ftlib;
+ FcConfig *fc;
+ Font *fonts;
+ u32 nfonts;
+ uv2 size;
+ i32 deltay;
} FontAtlas;
enum terminal_mode {
@@ -286,8 +290,6 @@ typedef struct {
enum terminal_mode mode;
char saved_title[1024];
-
- FT_Library ftlib;
} Term;
#include "config.h"