Ensure font data is free'd before other finalizers

Fixes #583
This commit is contained in:
Kovid Goyal 2018-05-29 07:18:07 +05:30
parent 9eb113802d
commit b886b4c6b2
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 21 additions and 12 deletions

View File

@ -1155,8 +1155,8 @@ finalize(void) {
Py_CLEAR(prerender_function);
Py_CLEAR(descriptor_for_idx);
free_font_groups();
if (harfbuzz_buffer) hb_buffer_destroy(harfbuzz_buffer);
free(group_state.groups);
if (harfbuzz_buffer) { hb_buffer_destroy(harfbuzz_buffer); harfbuzz_buffer = NULL; }
free(group_state.groups); group_state.groups = NULL; group_state.groups_capacity = 0;
}
static PyObject*
@ -1292,9 +1292,15 @@ create_test_font_group(PyObject *self UNUSED, PyObject *args) {
return Py_BuildValue("II", fg->cell_width, fg->cell_height);
}
static PyObject*
free_font_data(PyObject *self UNUSED, PyObject *args UNUSED) {
finalize();
Py_RETURN_NONE;
}
static PyMethodDef module_methods[] = {
METHODB(set_font_data, METH_VARARGS),
METHODB(free_font_data, METH_NOARGS),
METHODB(create_test_font_group, METH_VARARGS),
METHODB(sprite_map_set_layout, METH_VARARGS),
METHODB(test_sprite_position_for, METH_VARARGS),
@ -1309,10 +1315,6 @@ static PyMethodDef module_methods[] = {
bool
init_fonts(PyObject *module) {
if (Py_AtExit(finalize) != 0) {
PyErr_SetString(PyExc_RuntimeError, "Failed to register the fonts module at exit handler");
return false;
}
harfbuzz_buffer = hb_buffer_create();
if (harfbuzz_buffer == NULL || !hb_buffer_allocation_successful(harfbuzz_buffer) || !hb_buffer_pre_allocate(harfbuzz_buffer, 2048)) { PyErr_NoMemory(); return false; }
hb_buffer_set_cluster_level(harfbuzz_buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);

View File

@ -15,8 +15,8 @@ from .constants import (
appname, config_dir, glfw_path, is_macos, is_wayland, logo_data_file
)
from .fast_data_types import (
create_os_window, glfw_init, glfw_terminate, set_default_window_icon,
set_options
create_os_window, free_font_data, glfw_init, glfw_terminate,
set_default_window_icon, set_options
)
from .fonts.box_drawing import set_scale
from .fonts.render import set_font_family
@ -38,10 +38,7 @@ def init_graphics():
return glfw_module
def run_app(opts, args):
set_scale(opts.box_drawing_scale)
set_options(opts, is_wayland, args.debug_gl, args.debug_font_fallback)
set_font_family(opts)
def _run_app(opts, args):
with cached_values_for(run_app.cached_values_name) as cached_values:
with startup_notification_handler(extra_callback=run_app.first_window_callback) as pre_show_callback:
window_id = create_os_window(
@ -60,6 +57,16 @@ def run_app(opts, args):
boss.destroy()
def run_app(opts, args):
set_scale(opts.box_drawing_scale)
set_options(opts, is_wayland, args.debug_gl, args.debug_font_fallback)
set_font_family(opts)
try:
_run_app(opts, args)
finally:
free_font_data() # must free font data before glfw/freetype/fontconfig/opengl etc are finalized
run_app.cached_values_name = 'main'
run_app.first_window_callback = lambda window_handle: None
run_app.initial_window_size_func = initial_window_size_func