10 #include "../../stdafx.h"
11 #include "../../debug.h"
12 #include "../../fontdetection.h"
13 #include "../../string_func.h"
14 #include "../../strings_func.h"
16 #include <fontconfig/fontconfig.h>
23 #include FT_FREETYPE_H
25 extern FT_Library _library;
30 FT_Error err = FT_Err_Cannot_Open_Resource;
33 ShowInfo(
"Unable to load font configuration");
37 auto fc_instance = FcConfigReference(
nullptr);
38 assert(fc_instance !=
nullptr);
48 font_family =
stredup(font_name);
49 font_style = strchr(font_family,
',');
50 if (font_style !=
nullptr) {
53 while (*font_style ==
' ' || *font_style ==
'\t') font_style++;
57 pat = FcNameParse((FcChar8 *)font_family);
58 if (font_style !=
nullptr) FcPatternAddString(pat, FC_STYLE, (FcChar8 *)font_style);
59 FcConfigSubstitute(
nullptr, pat, FcMatchPattern);
60 FcDefaultSubstitute(pat);
61 fs = FcFontSetCreate();
62 match = FcFontMatch(
nullptr, pat, &result);
64 if (fs !=
nullptr && match !=
nullptr) {
70 FcFontSetAdd(fs, match);
72 for (i = 0; err != FT_Err_Ok && i < fs->nfont; i++) {
74 if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, &file) == FcResultMatch &&
75 FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) == FcResultMatch &&
76 FcPatternGetString(fs->fonts[i], FC_STYLE, 0, &style) == FcResultMatch &&
77 FcPatternGetInteger(fs->fonts[i], FC_INDEX, 0, &index) == FcResultMatch) {
80 if (font_style !=
nullptr && strcasecmp(font_style, (
char *)style) != 0)
continue;
85 if (strcasecmp(font_family, (
char *)family) == 0) {
86 err = FT_New_Face(_library, (
char *)file, index, face);
93 FcPatternDestroy(pat);
95 FcConfigDestroy(fc_instance);
107 if (!FcInit())
return ret;
109 auto fc_instance = FcConfigReference(
nullptr);
110 assert(fc_instance !=
nullptr);
117 char *split = strchr(lang,
'_');
118 if (split !=
nullptr) *split =
'\0';
121 FcPattern *pat = FcNameParse((FcChar8 *)lang);
123 FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SPACING, FC_SLANT, FC_WEIGHT,
nullptr);
125 FcFontSet *fs = FcFontList(
nullptr, pat, os);
128 FcObjectSetDestroy(os);
129 FcPatternDestroy(pat);
132 int best_weight = -1;
133 const char *best_font =
nullptr;
135 for (
int i = 0; i < fs->nfont; i++) {
136 FcPattern *font = fs->fonts[i];
138 FcChar8 *file =
nullptr;
139 FcResult res = FcPatternGetString(font, FC_FILE, 0, &file);
140 if (res != FcResultMatch || file ==
nullptr) {
146 FcPatternGetInteger(font, FC_SPACING, 0, &value);
147 if (callback->
Monospace() != (value == FC_MONO) && value != FC_DUAL)
continue;
150 FcPatternGetInteger(font, FC_SLANT, 0, &value);
151 if (value != 0)
continue;
154 FcPatternGetInteger(font, FC_WEIGHT, 0, &value);
155 if (value <= best_weight)
continue;
160 Debug(fontcache, 1,
"Font \"{}\" misses{} glyphs", file, missing ?
"" :
" no");
164 best_font = (
const char *)file;
168 if (best_font !=
nullptr) {
175 FcFontSetDestroy(fs);
178 FcConfigDestroy(fc_instance);