From ccc370e1c474c6eecdaa8c485e117a054b23fe00 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 15 May 2021 10:41:54 +0530 Subject: [PATCH] Dont initialize FontConfig when importing fast_data_types This reduces the import time for fast_data_types by 12ms on my machine. FontConfig initialization is very slow and it is only needed by the main kitty program, however fast_data_types is imported in kittens and remote control as well, where FontConfig is useless. --- kitty/fontconfig.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/kitty/fontconfig.c b/kitty/fontconfig.c index 3826f820c..3c0db030c 100644 --- a/kitty/fontconfig.c +++ b/kitty/fontconfig.c @@ -16,6 +16,25 @@ #define FC_COLOR "color" #endif + +static bool initialized = false; + +static void +ensure_initialized(void) { + if (!initialized) { + if (!FcInit()) fatal("Failed to initialize fontconfig library"); + initialized = true; + } +} + +static void +finalize(void) { + if (initialized) { + FcFini(); + initialized = false; + } +} + static inline PyObject* pybool(FcBool x) { PyObject *ans = x ? Py_True: Py_False; Py_INCREF(ans); return ans; } @@ -109,6 +128,7 @@ font_set(FcFontSet *fs) { static PyObject* fc_list(PyObject UNUSED *self, PyObject *args) { + ensure_initialized(); int allow_bitmapped_fonts = 0, spacing = -1; PyObject *ans = NULL; FcObjectSet *os = NULL; @@ -198,6 +218,7 @@ end: bool information_for_font_family(const char *family, bool bold, bool italic, FontConfigFace *ans) { + ensure_initialized(); memset(ans, 0, sizeof(FontConfigFace)); FcPattern *pat = FcPatternCreate(); bool ok = false; @@ -214,6 +235,7 @@ end: static PyObject* fc_match(PyObject UNUSED *self, PyObject *args) { + ensure_initialized(); char *family = NULL; int bold = 0, italic = 0, allow_bitmapped_fonts = 0, spacing = FC_MONO; double size_in_pts = 0, dpi = 0; @@ -248,6 +270,7 @@ end: static PyObject* fc_match_postscript_name(PyObject UNUSED *self, PyObject *args) { + ensure_initialized(); const char *postscript_name = NULL; FcPattern *pat = NULL; PyObject *ans = NULL; @@ -269,6 +292,7 @@ end: PyObject* specialize_font_descriptor(PyObject *base_descriptor, FONTS_DATA_HANDLE fg) { + ensure_initialized(); PyObject *p = PyDict_GetItemString(base_descriptor, "path"), *ans = NULL; PyObject *idx = PyDict_GetItemString(base_descriptor, "index"); if (p == NULL) { PyErr_SetString(PyExc_ValueError, "Base descriptor has no path"); return NULL; } @@ -292,6 +316,7 @@ end: bool fallback_font(char_type ch, const char *family, bool bold, bool italic, bool prefer_color, FontConfigFace *ans) { + ensure_initialized(); memset(ans, 0, sizeof(FontConfigFace)); bool ok = false; FcPattern *pat = FcPatternCreate(); @@ -310,6 +335,7 @@ end: PyObject* create_fallback_face(PyObject UNUSED *base_face, CPUCell* cell, bool bold, bool italic, bool emoji_presentation, FONTS_DATA_HANDLE fg) { + ensure_initialized(); PyObject *ans = NULL; FcPattern *pat = FcPatternCreate(); if (pat == NULL) return PyErr_NoMemory(); @@ -336,11 +362,7 @@ static PyMethodDef module_methods[] = { bool init_fontconfig_library(PyObject *module) { - if (!FcInit()) { - PyErr_SetString(PyExc_RuntimeError, "Failed to initialize the fontconfig library"); - return false; - } - register_at_exit_cleanup_func(FONTCONFIG_CLEANUP_FUNC, FcFini); + register_at_exit_cleanup_func(FONTCONFIG_CLEANUP_FUNC, finalize); if (PyModule_AddFunctions(module, module_methods) != 0) return false; PyModule_AddIntMacro(module, FC_WEIGHT_REGULAR); PyModule_AddIntMacro(module, FC_WEIGHT_MEDIUM);