Fix preview rendering when height of previewed font greater than cell height

This commit is contained in:
Kovid Goyal
2024-05-27 20:05:05 +05:30
parent 9782833308
commit e2919a0f2d
8 changed files with 49 additions and 33 deletions

View File

@@ -749,11 +749,13 @@ render_sample_text(CTFace *self, PyObject *args) {
CTFontRef font = self->ct_font;
PyObject *ptext;
if (!PyArg_ParseTuple(args, "Ukk|k", &ptext, &canvas_width, &canvas_height, &fg)) return NULL;
RAII_PyObject(pbuf, PyBytes_FromStringAndSize(NULL, sizeof(pixel) * canvas_width * canvas_height));
if (!pbuf) return NULL;
unsigned int cell_width, cell_height, baseline, underline_position, underline_thickness, strikethrough_position, strikethrough_thickness;
cell_metrics((PyObject*)self, &cell_width, &cell_height, &baseline, &underline_position, &underline_thickness, &strikethrough_position, &strikethrough_thickness);
size_t num_chars = PyUnicode_GET_LENGTH(ptext);
int num_chars_per_line = canvas_width / cell_width, num_of_lines = (int)ceil((float)num_chars / (float)num_chars_per_line);
canvas_height = MIN(canvas_height, num_of_lines * cell_height);
RAII_PyObject(pbuf, PyBytes_FromStringAndSize(NULL, sizeof(pixel) * canvas_width * canvas_height));
if (!pbuf) return NULL;
RAII_ALLOC(unichar, chars, calloc(sizeof(unichar), num_chars));
if (!chars) return PyErr_NoMemory();
for (size_t i = 0; i < num_chars; i++) chars[i] = PyUnicode_READ_CHAR(ptext, i);
@@ -786,8 +788,7 @@ render_sample_text(CTFace *self, PyObject *args) {
p[0] = r; p[1] = g; p[2] = b; p[3] = s[0];
}
end:
Py_INCREF(pbuf);
return pbuf;
return Py_BuildValue("OII", pbuf, cell_width, cell_height);
}

View File

@@ -439,7 +439,7 @@ class Face:
def identify_for_debug(self) -> str: ...
def postscript_name(self) -> str: ...
def set_size(self, sz_in_pts: float, dpi_x: float, dpi_y: float) -> None: ...
def render_sample_text(self, text: str, width: int, height: int, fg_color: int = 0xffffff) -> bytes: ...
def render_sample_text(self, text: str, width: int, height: int, fg_color: int = 0xffffff) -> Tuple[bytes, int, int]: ...
def get_variation(self) -> Optional[Dict[str, float]]: ...
def get_features(self) -> Dict[str, Optional[FeatureData]]: ...
def applied_features(self) -> Dict[str, str]: ...
@@ -476,7 +476,7 @@ class CTFace:
def identify_for_debug(self) -> str: ...
def postscript_name(self) -> str: ...
def set_size(self, sz_in_pts: float, dpi_x: float, dpi_y: float) -> None: ...
def render_sample_text(self, text: str, width: int, height: int, fg_color: int = 0xffffff) -> bytes: ...
def render_sample_text(self, text: str, width: int, height: int, fg_color: int = 0xffffff) -> Tuple[bytes, int, int]: ...
def get_variation(self) -> Optional[Dict[str, float]]: ...
def get_features(self) -> Dict[str, Optional[FeatureData]]: ...
def applied_features(self) -> Dict[str, str]: ...

View File

@@ -964,10 +964,12 @@ render_sample_text(Face *self, PyObject *args) {
unsigned long fg = 0xffffff;
PyObject *ptext;
if (!PyArg_ParseTuple(args, "Ukk|k", &ptext, &canvas_width, &canvas_height, &fg)) return NULL;
RAII_PyObject(pbuf, PyBytes_FromStringAndSize(NULL, sizeof(pixel) * canvas_width * canvas_height));
if (!pbuf) return NULL;
unsigned int cell_width, cell_height, baseline, underline_position, underline_thickness, strikethrough_position, strikethrough_thickness;
cell_metrics((PyObject*)self, &cell_width, &cell_height, &baseline, &underline_position, &underline_thickness, &strikethrough_position, &strikethrough_thickness);
int num_chars_per_line = canvas_width / cell_width, num_of_lines = (int)ceil((float)PyUnicode_GET_LENGTH(ptext) / (float)num_chars_per_line);
canvas_height = MIN(canvas_height, num_of_lines * cell_height);
RAII_PyObject(pbuf, PyBytes_FromStringAndSize(NULL, sizeof(pixel) * canvas_width * canvas_height));
if (!pbuf) return NULL;
pixel *canvas = (pixel*)PyBytes_AS_STRING(pbuf);
memset(canvas, 0, PyBytes_GET_SIZE(pbuf));
if (cell_width > canvas_width) goto end;
@@ -996,8 +998,7 @@ render_sample_text(Face *self, PyObject *args) {
p[0] = r; p[1] = g; p[2] = b; p[3] = a;
}
end:
Py_INCREF(pbuf);
return pbuf;
return Py_BuildValue("OII", pbuf, cell_width, cell_height);
}