diff --git a/docs/CHANGES.txt b/docs/CHANGES.txt index 3987011e4..7bda9fed1 100644 --- a/docs/CHANGES.txt +++ b/docs/CHANGES.txt @@ -35,7 +35,6 @@ https://tuxpaint.org/ entries found in system-wide and user-level FontConfig config files. This allows more fonts, and user-specific fonts, to be found & loaded. - It looks for: - - FIXME: (Windows) - `./etc/fonts/fonts.conf` (ships with Tux Paint) (Windows) - `$FONTCONFIG_PATH/fonts.conf` (macOS/iOS, Linux/Unix) - or `/etc/fonts/fonts.conf` (Linux/Unix) @@ -45,7 +44,7 @@ https://tuxpaint.org/ - FIXME: ??? (ships with Tux Paint) (macOS) - Note: This adds a build dependency on `libxml-2.0`. Bill Kendrick - h/t Mark Kim & Luc Schrijvers + h/t Mark Kim, Luc Schrijvers, & Shin-ichi TOYAMA + Tux Paint on Windows loads user fonts. (from e.g., `C:\Users\\AppData\Local\Microsoft\Windows\Fonts`) diff --git a/src/fonts.c b/src/fonts.c index ab6352907..bab9d2822 100644 --- a/src/fonts.c +++ b/src/fonts.c @@ -52,6 +52,15 @@ #endif +/* Enums representing the "prefix" attributes Tux Paint understands + in "fonts.conf" `` tags */ +enum { + FC_PREFIX_NONE, /* if none, "default", or "cwd" */ + FC_PREFIX_XDG, /* if "xdg", use $XDG_DATA_HOME */ + FC_PREFIX_RELATIVE, /* if "relative", relative to the "fonts.conf" where the `` tag exists */ +}; + + /* The following section renames global variables defined in SDL2_Pango.h to avoid errors during linking. It is okay to rename these variables because they are constants. @@ -998,8 +1007,6 @@ static void loadfonts(SDL_Surface *screen, SDL_Texture *texture, SDL_Renderer *r } -#define NUM_FONTCONFIG_CONFIG_PATHS 2 /* system-wide, and local/homedir */ - /** * Attempts to allocate space for a char * array to hold * a set of fontconfig config file paths for load_user_fonts() to @@ -1222,12 +1229,23 @@ char * * malloc_fontconfig_config_paths(int num_to_malloc, int * num_actually_ma { if (xmlStrcmp(cur->name, (const xmlChar *) "dir") == 0) { - xmlChar * path; + xmlChar * path, * prefix; char * path_str; + char prefix_path[1024]; + int fontconfig_prefix = FC_PREFIX_NONE; - /* FIXME: We do not currently understand "" -bjk 2025.02.22 - (prefix may be one of "cwd"/"default", "xdg", or "relative"; - see https://www.freedesktop.org/software/fontconfig/fontconfig-user.html */ + /* Check for a "" attribute + (see https://www.freedesktop.org/software/fontconfig/fontconfig-user.html) */ + prefix = xmlGetProp(cur, (const xmlChar *) "prefix"); + if (prefix != NULL) + { + if (xmlStrcmp(prefix, (const xmlChar *) "xdg") == 0) + fontconfig_prefix = FC_PREFIX_XDG; + else if (xmlStrcmp(prefix, (const xmlChar *) "relative") == 0) + fontconfig_prefix = FC_PREFIX_RELATIVE; + + xmlFree(prefix); + } /* Note: As we already look for both system and user fonts on Windows, we'll just ignore "WINDOWSUSERFONTDIR" and "WINDOWSFONTDIR" magic paths; @@ -1235,7 +1253,6 @@ char * * malloc_fontconfig_config_paths(int num_to_malloc, int * num_actually_ma See https://gitlab.freedesktop.org/fontconfig/fontconfig/-/blob/main/src/fcxml.c */ path = xmlNodeGetContent(cur); - if (path != NULL) { path_str = strdup((char *) path /* FIXME: is this cast safe? -bjk 2024.12.29 */); @@ -1260,7 +1277,43 @@ char * * malloc_fontconfig_config_paths(int num_to_malloc, int * num_actually_ma #endif #endif - /* Try to load fonts from the location found in the fonts.conf's tag */ + /* Apply any "prefix" attribute of the tag: */ + + prefix_path[0] = '\0'; + if (fontconfig_prefix == FC_PREFIX_XDG) + { + /* FIXME: Use xdg function */ + if (getenv("XDG_DATA_HOME") != NULL) + { + snprintf(prefix_path, sizeof(prefix_path), "%s/", getenv("XDG_DATA_HOME")); + } + else if (getenv("HOME") != NULL) + { + snprintf(prefix_path, sizeof(prefix_path), "%s/.local/share/", getenv("HOME")); + } + } + else if (fontconfig_prefix == FC_PREFIX_RELATIVE) + { + /* FIXME */ + printf("fonts.conf not supported yet!\n"); + } + + if (prefix_path[0] != '\0') + { + char * tmp_str; + size_t len; + + len = strlen(path_str) + strlen(prefix_path); + tmp_str = (char *) malloc(sizeof(char *) * (len + 1)); + if (tmp_str != NULL) + { + snprintf(tmp_str, len, "%s%s", prefix_path, path_str); + free(path_str); + path_str = tmp_str; + } + } + + /* Try to load fonts from the location found in the fonts.conf's tag */ loadfonts(screen, texture, renderer, (char *) path_str); free(path_str); xmlFree(path);