Allow fc-list to return variable fonts

This commit is contained in:
Kovid Goyal 2024-04-19 13:42:52 +05:30
parent 9b3bb05a3a
commit 3ba2492e99
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 16 additions and 11 deletions

View File

@ -391,12 +391,10 @@ class FontConfigPattern(TypedDict):
scalable: bool
outline: bool
color: bool
variable: bool
def fc_list(
spacing: int = -1,
allow_bitmapped_fonts: bool = False
) -> Tuple[FontConfigPattern, ...]:
def fc_list(spacing: int = -1, allow_bitmapped_fonts: bool = False, only_variable: bool = False) -> Tuple[FontConfigPattern, ...]:
pass

View File

@ -186,6 +186,7 @@ pattern_as_dict(FcPattern *pat) {
S(FC_FULLNAME, full_name);
S(FC_POSTSCRIPT_NAME, postscript_name);
LS(FC_FONT_FEATURES, fontfeatures);
B(FC_VARIABLE, variable);
I(FC_WEIGHT, weight);
I(FC_WIDTH, width)
I(FC_SLANT, slant);
@ -229,22 +230,28 @@ font_set(FcFontSet *fs) {
#define AP(func, which, in, desc) if (!func(pat, which, in)) { PyErr_Format(PyExc_ValueError, "Failed to add %s to fontconfig pattern", desc, NULL); goto end; }
static PyObject*
fc_list(PyObject UNUSED *self, PyObject *args) {
fc_list(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
ensure_initialized();
int allow_bitmapped_fonts = 0, spacing = -1;
int allow_bitmapped_fonts = 0, spacing = -1, only_variable = 0;
PyObject *ans = NULL;
FcObjectSet *os = NULL;
FcPattern *pat = NULL;
FcFontSet *fs = NULL;
if (!PyArg_ParseTuple(args, "|ip", &spacing, &allow_bitmapped_fonts)) return NULL;
static char *kwds[] = {"spacing", "allow_bitmapped_fonts", "only_variable", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kw, "|ipp", kwds, &spacing, &allow_bitmapped_fonts, &only_variable)) return NULL;
pat = FcPatternCreate();
if (pat == NULL) return PyErr_NoMemory();
if (!allow_bitmapped_fonts) {
AP(FcPatternAddBool, FC_OUTLINE, true, "outline");
AP(FcPatternAddBool, FC_SCALABLE, true, "scalable");
AP(FcPatternAddBool, FC_OUTLINE, FcTrue, "outline");
AP(FcPatternAddBool, FC_SCALABLE, FcTrue, "scalable");
}
if (spacing > -1) AP(FcPatternAddInteger, FC_SPACING, spacing, "spacing");
os = FcObjectSetBuild(FC_FILE, FC_POSTSCRIPT_NAME, FC_FAMILY, FC_STYLE, FC_FULLNAME, FC_WEIGHT, FC_WIDTH, FC_SLANT, FC_HINT_STYLE, FC_INDEX, FC_HINTING, FC_SCALABLE, FC_OUTLINE, FC_COLOR, FC_SPACING, NULL);
#define basic_properties FC_FILE, FC_POSTSCRIPT_NAME, FC_FAMILY, FC_STYLE, FC_FULLNAME, FC_WEIGHT, FC_WIDTH, FC_SLANT, FC_HINT_STYLE, FC_INDEX, FC_HINTING, FC_SCALABLE, FC_OUTLINE, FC_COLOR, FC_SPACING
if (only_variable) {
AP(FcPatternAddBool, FC_VARIABLE, FcTrue, "variable");
os = FcObjectSetBuild(basic_properties, FC_VARIABLE, FC_FONT_VARIATIONS, NULL);
} else os = FcObjectSetBuild(basic_properties, NULL);
#undef basic_properties
if (!os) { PyErr_SetString(PyExc_ValueError, "Failed to create fontconfig object set"); goto end; }
fs = FcFontList(NULL, pat, os);
if (!fs) { PyErr_SetString(PyExc_ValueError, "Failed to create fontconfig font set"); goto end; }
@ -464,7 +471,7 @@ end:
#undef AP
static PyMethodDef module_methods[] = {
METHODB(fc_list, METH_VARARGS),
{"fc_list", (PyCFunction)(void (*) (void))(fc_list), METH_VARARGS | METH_KEYWORDS, NULL},
METHODB(fc_match, METH_VARARGS),
METHODB(fc_match_postscript_name, METH_VARARGS),
{NULL, NULL, 0, NULL} /* Sentinel */