Ensure fontconfig pattern dict has all keys with default values
This commit is contained in:
parent
189ec26dbc
commit
00dc8f0e23
1 changed files with 18 additions and 21 deletions
|
|
@ -147,39 +147,39 @@ pyspacing(int val) {
|
|||
#undef S
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
increment_and_return(PyObject *x) { if (x) Py_INCREF(x); return x; }
|
||||
|
||||
static PyObject*
|
||||
pattern_as_dict(FcPattern *pat) {
|
||||
PyObject *ans = Py_BuildValue("{ss}", "descriptor_type", "fontconfig"), *p = NULL, *list = NULL;
|
||||
RAII_PyObject(ans, Py_BuildValue("{ss}", "descriptor_type", "fontconfig"));
|
||||
if (ans == NULL) return NULL;
|
||||
|
||||
#define PS(x) PyUnicode_Decode((const char*)x, strlen((const char*)x), "UTF-8", "replace")
|
||||
|
||||
#define G(type, get, which, conv, name) { \
|
||||
#define G(type, get, which, conv, name, default) { \
|
||||
type out; \
|
||||
if (get(pat, which, 0, &out) == FcResultMatch) { \
|
||||
p = conv(out); if (p == NULL) goto exit; \
|
||||
if (PyDict_SetItemString(ans, #name, p) != 0) goto exit; \
|
||||
Py_CLEAR(p); \
|
||||
}}
|
||||
RAII_PyObject(p, conv(out)); \
|
||||
if (!p || PyDict_SetItemString(ans, #name, p) != 0) return NULL; \
|
||||
} else { RAII_PyObject(d, default); if (!d || PyDict_SetItemString(ans, #name, d) != 0) return NULL; } \
|
||||
}
|
||||
|
||||
#define L(type, get, which, conv, name) { \
|
||||
type out; int n = 0; \
|
||||
list = PyList_New(0); \
|
||||
if (!list) goto exit; \
|
||||
RAII_PyObject(list, PyList_New(0)); \
|
||||
if (!list) return NULL; \
|
||||
while (get(pat, which, n++, &out) == FcResultMatch) { \
|
||||
p = conv(out); if (p == NULL) goto exit; \
|
||||
if (PyList_Append(list, p) != 0) goto exit; \
|
||||
Py_CLEAR(p); \
|
||||
RAII_PyObject(p, conv(out)); \
|
||||
if (!p || PyList_Append(list, p) != 0) return NULL; \
|
||||
} \
|
||||
if (PyDict_SetItemString(ans, #name, list) != 0) goto exit; \
|
||||
Py_CLEAR(list); \
|
||||
if (PyDict_SetItemString(ans, #name, list) != 0) return NULL; \
|
||||
}
|
||||
#define S(which, key) G(FcChar8*, FcPatternGetString, which, PS, key)
|
||||
#define S(which, key) G(FcChar8*, FcPatternGetString, which, PS, key, PyUnicode_FromString(""))
|
||||
#define LS(which, key) L(FcChar8*, FcPatternGetString, which, PS, key)
|
||||
#define I(which, key) G(int, FcPatternGetInteger, which, PyLong_FromLong, key)
|
||||
#define B(which, key) G(int, FcPatternGetBool, which, pybool, key)
|
||||
#define E(which, key, conv) G(int, FcPatternGetInteger, which, conv, key)
|
||||
#define I(which, key) G(int, FcPatternGetInteger, which, PyLong_FromLong, key, PyLong_FromUnsignedLong(0))
|
||||
#define B(which, key) G(int, FcPatternGetBool, which, pybool, key, increment_and_return(Py_False))
|
||||
#define E(which, key, conv) G(int, FcPatternGetInteger, which, conv, key, PyLong_FromUnsignedLong(0))
|
||||
S(FC_FILE, path);
|
||||
S(FC_FAMILY, family);
|
||||
S(FC_STYLE, style);
|
||||
|
|
@ -199,11 +199,8 @@ pattern_as_dict(FcPattern *pat) {
|
|||
B(FC_OUTLINE, outline);
|
||||
B(FC_COLOR, color);
|
||||
E(FC_SPACING, spacing, pyspacing);
|
||||
exit:
|
||||
if (PyErr_Occurred()) Py_CLEAR(ans);
|
||||
Py_CLEAR(p);
|
||||
Py_CLEAR(list);
|
||||
|
||||
Py_INCREF(ans);
|
||||
return ans;
|
||||
#undef PS
|
||||
#undef S
|
||||
|
|
|
|||
Loading…
Reference in a new issue