Do not crash when failing to render a glyph, instead render the missing glyph and print an error msg to stderr

This commit is contained in:
Kovid Goyal 2017-09-29 11:57:17 +05:30
parent 7ddaa70498
commit 8d03d7216f
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 12 additions and 5 deletions

View File

@ -8,7 +8,7 @@ from collections import namedtuple
from functools import lru_cache from functools import lru_cache
from itertools import chain from itertools import chain
from kitty.fast_data_types import FT_PIXEL_MODE_GRAY, Face from kitty.fast_data_types import FT_PIXEL_MODE_GRAY, Face, FreeTypeError
from kitty.fonts.box_drawing import render_missing_glyph from kitty.fonts.box_drawing import render_missing_glyph
from kitty.utils import ceil_int, get_logical_dpi, safe_print, wcwidth, adjust_line_height from kitty.utils import ceil_int, get_logical_dpi, safe_print, wcwidth, adjust_line_height
@ -258,6 +258,9 @@ def render_cell(text=' ', bold=False, italic=False):
except FontNotFound as err: except FontNotFound as err:
safe_print('ERROR:', err, file=sys.stderr) safe_print('ERROR:', err, file=sys.stderr)
return missing_glyph(width) return missing_glyph(width)
except FreeTypeError as err:
safe_print('Failed to render text:', repr(text), 'with error:', err, file=sys.stderr)
return missing_glyph(width)
second = None second = None
if width == 2: if width == 2:
if bitmap_char.columns > cell_width: if bitmap_char.columns > cell_width:

View File

@ -18,6 +18,7 @@ typedef struct {
bool is_scalable; bool is_scalable;
} Face; } Face;
static PyObject* FreeType_Exception = NULL;
void void
set_freetype_error(const char* prefix, int err_code) { set_freetype_error(const char* prefix, int err_code) {
@ -41,12 +42,12 @@ set_freetype_error(const char* prefix, int err_code) {
while(ft_errors[i].err_msg != NULL) { while(ft_errors[i].err_msg != NULL) {
if (ft_errors[i].err_code == err_code) { if (ft_errors[i].err_code == err_code) {
PyErr_Format(PyExc_ValueError, "%s %s", prefix, ft_errors[i].err_msg); PyErr_Format(FreeType_Exception, "%s %s", prefix, ft_errors[i].err_msg);
return; return;
} }
i++; i++;
} }
PyErr_Format(PyExc_ValueError, "%s (error code: %d)", prefix, err_code); PyErr_Format(FreeType_Exception, "%s (error code: %d)", prefix, err_code);
} }
static FT_Library library; static FT_Library library;
@ -190,7 +191,7 @@ trim_to_width(Face UNUSED *self, PyObject *args) {
rows = PyLong_AsUnsignedLong(PyStructSequence_GET_ITEM(bitmap, 0)); rows = PyLong_AsUnsignedLong(PyStructSequence_GET_ITEM(bitmap, 0));
width = PyLong_AsUnsignedLong(PyStructSequence_GET_ITEM(bitmap, 1)); width = PyLong_AsUnsignedLong(PyStructSequence_GET_ITEM(bitmap, 1));
extra = width - cell_width; extra = width - cell_width;
if (extra >= cell_width) { PyErr_SetString(PyExc_ValueError, "Too large for trimming"); return NULL; } if (extra >= cell_width) { PyErr_SetString(FreeType_Exception, "Too large for trimming"); return NULL; }
PyObject *ans = PyStructSequence_New(&BitmapType); PyObject *ans = PyStructSequence_New(&BitmapType);
if (ans == NULL) return PyErr_NoMemory(); if (ans == NULL) return PyErr_NoMemory();
src = (unsigned char*)PyByteArray_AS_STRING(PyStructSequence_GET_ITEM(bitmap, 3)); src = (unsigned char*)PyByteArray_AS_STRING(PyStructSequence_GET_ITEM(bitmap, 3));
@ -267,13 +268,16 @@ free_freetype() {
bool bool
init_freetype_library(PyObject *m) { init_freetype_library(PyObject *m) {
FreeType_Exception = PyErr_NewException("fast_data_types.FreeTypeError", NULL, NULL);
if (FreeType_Exception == NULL) return false;
if (PyModule_AddObject(m, "FreeTypeError", FreeType_Exception) != 0) return false;
int error = FT_Init_FreeType(&library); int error = FT_Init_FreeType(&library);
if (error) { if (error) {
set_freetype_error("Failed to initialize FreeType library, with error:", error); set_freetype_error("Failed to initialize FreeType library, with error:", error);
return false; return false;
} }
if (Py_AtExit(free_freetype) != 0) { if (Py_AtExit(free_freetype) != 0) {
PyErr_SetString(PyExc_RuntimeError, "Failed to register the freetype library at exit handler"); PyErr_SetString(FreeType_Exception, "Failed to register the freetype library at exit handler");
return false; return false;
} }
if (PyStructSequence_InitType2(&GlpyhMetricsType, &gm_desc) != 0) return false; if (PyStructSequence_InitType2(&GlpyhMetricsType, &gm_desc) != 0) return false;