vtgl

terminal emulator implemented in OpenGL
git clone anongit@rnpnr.xyz:vtgl.git
Log | Files | Refs | Feed | LICENSE

Commit: 7041d1c39b7230d118a70270536b218fc5ba67c4
Parent: 22cc7c97755d177b070650ec2e9781a05ba81d11
Author: Randy Palamar
Date:   Sun, 18 Aug 2024 13:35:29 -0600

use fontconfig to find fonts

Diffstat:
Mbuild.sh | 4++--
Mconfig.def.h | 3+++
Mfont.c | 68+++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Mmain.c | 5+----
Mutil.h | 20+++++++++++---------
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"