mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-08-05 21:10:11 +03:00
consider all fonts when computing font family metrics
This commit is contained in:
parent
5aab9065a6
commit
90816952cf
|
@ -1016,6 +1016,14 @@ class FreeTypeFontFamily:
|
||||||
start[1],
|
start[1],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def getmetrics(self):
|
||||||
|
"""
|
||||||
|
:return: A tuple of the maximum font ascent (the distance from the baseline to
|
||||||
|
the highest outline point) and maximum descent (the distance from the
|
||||||
|
baseline to the lowest outline point, a negative value)
|
||||||
|
"""
|
||||||
|
return self.font.ascent, self.font.descent
|
||||||
|
|
||||||
|
|
||||||
class TransposedFont:
|
class TransposedFont:
|
||||||
"""Wrapper for writing rotated or mirrored text"""
|
"""Wrapper for writing rotated or mirrored text"""
|
||||||
|
|
|
@ -386,6 +386,42 @@ err:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FT_Pos
|
||||||
|
family_getascender(FontFamily *family) {
|
||||||
|
int i;
|
||||||
|
FT_Pos ascender = 0;
|
||||||
|
for (i = 0; i < family->font_count; i++) {
|
||||||
|
ascender = (ascender > family->faces[i]->size->metrics.ascender)
|
||||||
|
? ascender
|
||||||
|
: family->faces[i]->size->metrics.ascender;
|
||||||
|
}
|
||||||
|
return ascender;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FT_Pos
|
||||||
|
family_getdescender(FontFamily *family) {
|
||||||
|
int i;
|
||||||
|
FT_Pos descender = 0;
|
||||||
|
for (i = 0; i < family->font_count; i++) {
|
||||||
|
descender = (descender < family->faces[i]->size->metrics.descender)
|
||||||
|
? descender
|
||||||
|
: family->faces[i]->size->metrics.descender;
|
||||||
|
}
|
||||||
|
return descender;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FT_Pos
|
||||||
|
family_getheight(FontFamily *family) {
|
||||||
|
int i;
|
||||||
|
FT_Pos height = 0;
|
||||||
|
for (i = 0; i < family->font_count; i++) {
|
||||||
|
height = (height > family->faces[i]->size->metrics.height)
|
||||||
|
? height
|
||||||
|
: family->faces[i]->size->metrics.height;
|
||||||
|
}
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_RAQM
|
#ifdef HAVE_RAQM
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
|
@ -949,16 +985,16 @@ bounding_box_and_anchors(
|
||||||
}
|
}
|
||||||
switch (anchor[1]) {
|
switch (anchor[1]) {
|
||||||
case 'a': // ascender
|
case 'a': // ascender
|
||||||
y_anchor = PIXEL(family->faces[0]->size->metrics.ascender);
|
// this should be consistent with getmetrics()
|
||||||
|
y_anchor = PIXEL(family_getascender(family));
|
||||||
break;
|
break;
|
||||||
case 't': // top
|
case 't': // top
|
||||||
y_anchor = y_max;
|
y_anchor = y_max;
|
||||||
break;
|
break;
|
||||||
case 'm': // middle (ascender + descender) / 2
|
case 'm': // middle (ascender + descender) / 2
|
||||||
|
// this should be consistent with getmetrics()
|
||||||
y_anchor = PIXEL(
|
y_anchor = PIXEL(
|
||||||
(family->faces[0]->size->metrics.ascender + family->faces[0]->size->metrics.descender) /
|
(family_getascender(family) + family_getdescender(family)) / 2);
|
||||||
2
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
case 's': // horizontal baseline
|
case 's': // horizontal baseline
|
||||||
y_anchor = 0;
|
y_anchor = 0;
|
||||||
|
@ -967,7 +1003,8 @@ bounding_box_and_anchors(
|
||||||
y_anchor = y_min;
|
y_anchor = y_min;
|
||||||
break;
|
break;
|
||||||
case 'd': // descender
|
case 'd': // descender
|
||||||
y_anchor = PIXEL(family->faces[0]->size->metrics.descender);
|
// this should be consistent with getmetrics()
|
||||||
|
y_anchor = PIXEL(family_getdescender(family));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto bad_anchor;
|
goto bad_anchor;
|
||||||
|
@ -1897,6 +1934,33 @@ static PyMethodDef family_methods[] = {
|
||||||
*/
|
*/
|
||||||
{NULL, NULL}};
|
{NULL, NULL}};
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
family_getattr_ascent(FontFamilyObject *self, void *closure) {
|
||||||
|
return PyLong_FromLong(PIXEL(family_getascender(&self->data)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
family_getattr_descent(FontFamilyObject *self, void *closure) {
|
||||||
|
return PyLong_FromLong(-PIXEL(family_getdescender(&self->data)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
family_getattr_height(FontFamilyObject *self, void *closure) {
|
||||||
|
return PyLong_FromLong(PIXEL(family_getheight(&self->data)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct PyGetSetDef family_getsetters[] = {
|
||||||
|
//{"family", (getter)font_getattr_family},
|
||||||
|
//{"style", (getter)font_getattr_style},
|
||||||
|
{"ascent", (getter)family_getattr_ascent},
|
||||||
|
{"descent", (getter)family_getattr_descent},
|
||||||
|
{"height", (getter)family_getattr_height},
|
||||||
|
//{"x_ppem", (getter)font_getattr_x_ppem},
|
||||||
|
//{"y_ppem", (getter)font_getattr_y_ppem},
|
||||||
|
//{"glyphs", (getter)font_getattr_glyphs},
|
||||||
|
{NULL}};
|
||||||
|
|
||||||
|
|
||||||
static PyTypeObject FontFamily_Type = {
|
static PyTypeObject FontFamily_Type = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0) "FontFamily",
|
PyVarObject_HEAD_INIT(NULL, 0) "FontFamily",
|
||||||
|
@ -1928,7 +1992,7 @@ static PyTypeObject FontFamily_Type = {
|
||||||
0, /*tp_iternext*/
|
0, /*tp_iternext*/
|
||||||
family_methods, /*tp_methods*/
|
family_methods, /*tp_methods*/
|
||||||
0, /*tp_members*/
|
0, /*tp_members*/
|
||||||
0, /*TODO tp_getset*/
|
family_getsetters, /* tp_getset*/
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyMethodDef _functions[] = {
|
static PyMethodDef _functions[] = {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user