Make use of fontconfig where detected by cmake, to avoid having to make sense of the system's font directory mess.

This commit is contained in:
Shpoike 2023-04-23 05:33:38 +01:00
parent 0509f7c83c
commit 76cbc3c019
3 changed files with 125 additions and 5 deletions

View File

@ -185,6 +185,15 @@ IF(FREETYPE_FOUND)
INCLUDE_DIRECTORIES( ${FREETYPE_INCLUDE_DIRS} )
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};LIBFREETYPE_STATIC)
SET(FTE_LIBS ${FTE_LIBS} ${FREETYPE_LIBRARIES})
FIND_PACKAGE(Fontconfig)
IF(Fontconfig_FOUND)
INCLUDE_DIRECTORIES( ${Fontconfig_INCLUDE_DIRS} )
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};LIBFONTCONFIG_STATIC)
SET(FTE_LIBS ${FTE_LIBS} ${Fontconfig_LIBRARIES})
ELSEIF()
MESSAGE(WARNING "fontconfig library NOT available. I hope you're not using any system fonts.")
ENDIF()
ELSE()
MESSAGE(WARNING "freetype library NOT available. I hope you're okay with ascii.")
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_FREETYPE)

View File

@ -1075,7 +1075,22 @@ void QDECL R2D_Conback_Callback(struct cvar_s *var, char *oldvalue)
}
#ifdef AVAIL_FREETYPE
#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT) && !defined(_XBOX)
#if defined(LIBFONTCONFIG_STATIC)
#include <fontconfig/fontconfig.h>
static int QDECL SortCompareFonts(const void *av, const void *bv)
{ //qsort compare
const FcPattern *af = *(FcPattern *const*const)av, *bf = *(FcPattern *const*const)bv;
FcChar8 *as, *bs;
int r = 0;
if (FcPatternGetString(af, FC_FAMILY, 0, &as) == FcResultMatch && FcPatternGetString(bf, FC_FAMILY, 0, &bs) == FcResultMatch)
{
r = strcmp(as, bs);
if (!r && FcPatternGetString(af, FC_STYLE, 0, &as) == FcResultMatch && FcPatternGetString(bf, FC_STYLE, 0, &bs) == FcResultMatch)
r = strcmp(as, bs);
}
return r;
}
#elif defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT) && !defined(_XBOX)
#include <windows.h>
qboolean R2D_Font_WasAdded(char *buffer, char *fontfilename)
{
@ -1181,6 +1196,45 @@ void R2D_Font_Changed(void)
{
#ifndef AVAIL_FREETYPE
Cvar_Set(&gl_font, "");
#elif defined(LIBFONTCONFIG_STATIC)
Cvar_Set(&gl_font, "");
{
FcConfig *config = FcInitLoadConfigAndFonts();
FcPattern *pat = FcPatternCreate();
FcObjectSet *os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, (char *) 0);
FcFontSet *fs = FcFontList(config, pat, os);
if (fs)
{
int i;
FcChar8 *oldfam = NULL;
FcPattern **fonts = BZ_Malloc(sizeof(*fonts)*fs->nfont);
memcpy(fonts, fs->fonts, sizeof(*fonts)*fs->nfont);
qsort(fonts, fs->nfont, sizeof(*fonts), SortCompareFonts);
for (i=0; fs && i < fs->nfont; i++)
{
FcPattern *font = fonts[i];
FcChar8 *style, *family;
if (FcPatternGetString(font, FC_FAMILY, 0, &family) == FcResultMatch && FcPatternGetString(font, FC_STYLE, 0, &style) == FcResultMatch)
{
if (!oldfam || strcmp(oldfam, family))
{
if (oldfam)
Con_Printf("\n");
oldfam = family;
Con_Printf("^["S_COLOR_WHITE"%s\\type\\/gl_font %s^]: ", family, family);
}
Con_Printf(" \t^[%s\\type\\/gl_font %s?style=%s^]", style, family, style);
}
}
if (oldfam)
Con_Printf("\n");
BZ_Free(fonts);
FcFontSetDestroy(fs);
}
FcObjectSetDestroy(os);
FcPatternDestroy(pat);
}
#elif defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT) && !defined(_XBOX)
BOOL (APIENTRY *pChooseFontW)(LPCHOOSEFONTW) = NULL;
dllfunction_t funcs[] =

View File

@ -13,6 +13,20 @@
#endif
#include <ctype.h>
/* Font Names:
primaryface[,altface[...]][?primaryarg[&arg[...]]][:[secondaryface[,altface[...]]][?secondaryargs]]
args:
col=r,g,b -- tint the font (overriding the game's normal tint). only arg allowed when the secondary face is omitted.
fmt=q -- quake-style raster font with quake's own codepage (no fallbacks needed for the weird glyphs).
fmt=l -- quake-style raster font with io8859-1(latin-1) codepage
fmt=w -- quake-style raster font with windows1252 codepage (for more glyphs than latin-1)
fmt=k -- quake-style raster font with koi8-u codepage (apparently its somewhat common in the quake community)
fmt=h -- halflife-style all-on-one-line raster font
aspect=0.5 -- raster font is squished horizontally
style -- list of modifiets for inexact family font matching for system fonts
*/
void Font_Init(void);
void Font_Shutdown(void);
struct font_s *Font_LoadFont(const char *fontfilename, float height, float scale, int outline, unsigned int flags);
@ -1762,6 +1776,9 @@ qboolean Font_LoadKexFont(struct font_s *f, int fheight, const char *fontfilenam
}
#ifdef AVAIL_FREETYPE
#if defined(LIBFONTCONFIG_STATIC)
#include <fontconfig/fontconfig.h>
#endif
extern cvar_t dpcompat_smallerfonts;
int Font_ChangeFTSize(fontface_t *qface, int pixelheight)
{
@ -1813,7 +1830,7 @@ int Font_ChangeFTSize(fontface_t *qface, int pixelheight)
}
return pixelheight;
}
qboolean Font_LoadFreeTypeFont(struct font_s *f, int height, const char *fontfilename)
qboolean Font_LoadFreeTypeFont(struct font_s *f, int height, const char *fontfilename, const char *styles)
{
fontface_t *qface;
FT_Face face = NULL;
@ -1913,7 +1930,34 @@ qboolean Font_LoadFreeTypeFont(struct font_s *f, int height, const char *fontfil
}
}
#if defined(_WIN32)
#if defined(LIBFONTCONFIG_STATIC)
if (error && !strchr(fontfilename, '/'))
{
FcConfig *config = FcInitLoadConfigAndFonts();
FcResult res;
FcPattern *font;
FcPattern *pat;
//FcNameParse takes something of the form: "family:style1:style2". we already swapped spaces for : in styles.
if (styles)
pat = FcNameParse((const FcChar8*)va("%s:%s", fontfilename, styles));
else
pat = FcNameParse((const FcChar8*)fontfilename);
FcConfigSubstitute(config, pat, FcMatchPattern);
FcDefaultSubstitute(pat);
// find the font
font = FcFontMatch(config, pat, &res);
if (font)
{
FcChar8 *file = NULL;
if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch)
error = pFT_New_Face(fontlib, file, 0, &face); //'file' should be a system path
FcPatternDestroy(font);
}
FcPatternDestroy(pat);
}
#elif defined(_WIN32)
if (error)
{
static qboolean firsttime = true;
@ -2285,6 +2329,7 @@ struct font_s *Font_LoadFont(const char *fontfilename, float vheight, float scal
char *parms;
int height = ((vheight * vid.rotpixelheight)/vid.height) + 0.5;
char facename[MAX_QPATH*12];
char *styles = NULL;
struct charcache_s *c;
float aspect = 1;
enum fontfmt_e fmt = FMT_AUTO;
@ -2356,12 +2401,24 @@ struct font_s *Font_LoadFont(const char *fontfilename, float vheight, float scal
aspect = strtod(t, &t);
parms = t;
}
if (!strncmp(parms, "style=", 6))
{
char *t = parms+6;
styles = t;
while (*t && *t != '&')
{
if (*t == ' ')
*t = ':';
t++;
}
parms = t;
}
while(*parms && *parms != '&')
parms++;
if (*parms == '&')
{
parms++;
*parms++ = 0;
continue;
}
}
@ -2547,7 +2604,7 @@ struct font_s *Font_LoadFont(const char *fontfilename, float vheight, float scal
else if (fmt == FMT_HORIZONTAL)
success = Font_LoadHorizontalFont(f, height, start);
#ifdef AVAIL_FREETYPE
else if (fmt == FMT_AUTO && Font_LoadFreeTypeFont(f, height, start))
else if (fmt == FMT_AUTO && Font_LoadFreeTypeFont(f, height, start, styles))
success = true;
#endif
else