mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-28 19:06:18 +03:00
Fixed bugs in calculating text size (#3864)
Fixed bugs in calculating text size
This commit is contained in:
commit
26182dde13
BIN
Tests/fonts/ArefRuqaa-Regular.ttf
Normal file
BIN
Tests/fonts/ArefRuqaa-Regular.ttf
Normal file
Binary file not shown.
|
@ -3,6 +3,7 @@ NotoNastaliqUrdu-Regular.ttf, from https://github.com/googlei18n/noto-fonts
|
||||||
NotoSansJP-Thin.otf, from https://www.google.com/get/noto/help/cjk/
|
NotoSansJP-Thin.otf, from https://www.google.com/get/noto/help/cjk/
|
||||||
AdobeVFPrototype.ttf, from https://github.com/adobe-fonts/adobe-variable-font-prototype
|
AdobeVFPrototype.ttf, from https://github.com/adobe-fonts/adobe-variable-font-prototype
|
||||||
TINY5x3GX.ttf, from http://velvetyne.fr/fonts/tiny
|
TINY5x3GX.ttf, from http://velvetyne.fr/fonts/tiny
|
||||||
|
ArefRuqaa-Regular.ttf, from https://github.com/google/fonts/tree/master/ofl/arefruqaa
|
||||||
|
|
||||||
All of the above fonts are published under the SIL Open Font License (OFL) v1.1 (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL), which allows you to copy, modify, and redistribute them if you need to.
|
All of the above fonts are published under the SIL Open Font License (OFL) v1.1 (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL), which allows you to copy, modify, and redistribute them if you need to.
|
||||||
|
|
||||||
|
|
BIN
Tests/images/test_x_max_and_y_offset.png
Normal file
BIN
Tests/images/test_x_max_and_y_offset.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 810 B |
Binary file not shown.
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
@ -159,6 +159,18 @@ class TestImagecomplextext(PillowTestCase):
|
||||||
|
|
||||||
self.assert_image_similar(im, target_img, .5)
|
self.assert_image_similar(im, target_img, .5)
|
||||||
|
|
||||||
|
def test_x_max_and_y_offset(self):
|
||||||
|
ttf = ImageFont.truetype("Tests/fonts/ArefRuqaa-Regular.ttf", 40)
|
||||||
|
|
||||||
|
im = Image.new(mode='RGB', size=(50, 100))
|
||||||
|
draw = ImageDraw.Draw(im)
|
||||||
|
draw.text((0, 0), 'لح', font=ttf, fill=500)
|
||||||
|
|
||||||
|
target = 'Tests/images/test_x_max_and_y_offset.png'
|
||||||
|
target_img = Image.open(target)
|
||||||
|
|
||||||
|
self.assert_image_similar(im, target_img, .5)
|
||||||
|
|
||||||
def test_language(self):
|
def test_language(self):
|
||||||
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
|
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
|
||||||
|
|
||||||
|
|
|
@ -618,7 +618,7 @@ text_layout(PyObject* string, FontObject* self, const char* dir, PyObject *featu
|
||||||
static PyObject*
|
static PyObject*
|
||||||
font_getsize(FontObject* self, PyObject* args)
|
font_getsize(FontObject* self, PyObject* args)
|
||||||
{
|
{
|
||||||
int x_max, x_min, y_max, y_min;
|
int x_position, x_max, x_min, y_max, y_min;
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
int xoffset, yoffset;
|
int xoffset, yoffset;
|
||||||
int horizontal_dir;
|
int horizontal_dir;
|
||||||
|
@ -634,18 +634,18 @@ font_getsize(FontObject* self, PyObject* args)
|
||||||
if (!PyArg_ParseTuple(args, "O|zOz:getsize", &string, &dir, &features, &lang))
|
if (!PyArg_ParseTuple(args, "O|zOz:getsize", &string, &dir, &features, &lang))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
face = NULL;
|
|
||||||
xoffset = yoffset = 0;
|
|
||||||
x_max = x_min = y_max = y_min = 0;
|
|
||||||
|
|
||||||
count = text_layout(string, self, dir, features, lang, &glyph_info, 0);
|
count = text_layout(string, self, dir, features, lang, &glyph_info, 0);
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
face = NULL;
|
||||||
|
xoffset = yoffset = 0;
|
||||||
|
x_position = x_max = x_min = y_max = y_min = 0;
|
||||||
|
|
||||||
horizontal_dir = dir && strcmp(dir, "ttb") == 0 ? 0 : 1;
|
horizontal_dir = dir && strcmp(dir, "ttb") == 0 ? 0 : 1;
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
int index, error;
|
int index, error, offset, x_advanced;
|
||||||
FT_BBox bbox;
|
FT_BBox bbox;
|
||||||
FT_Glyph glyph;
|
FT_Glyph glyph;
|
||||||
face = self->face;
|
face = self->face;
|
||||||
|
@ -661,7 +661,7 @@ font_getsize(FontObject* self, PyObject* args)
|
||||||
if (horizontal_dir) {
|
if (horizontal_dir) {
|
||||||
if (face->glyph->metrics.horiBearingX < 0) {
|
if (face->glyph->metrics.horiBearingX < 0) {
|
||||||
xoffset = face->glyph->metrics.horiBearingX;
|
xoffset = face->glyph->metrics.horiBearingX;
|
||||||
x_max -= xoffset;
|
x_position -= xoffset;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (face->glyph->metrics.vertBearingY < 0) {
|
if (face->glyph->metrics.vertBearingY < 0) {
|
||||||
|
@ -674,20 +674,19 @@ font_getsize(FontObject* self, PyObject* args)
|
||||||
FT_Get_Glyph(face->glyph, &glyph);
|
FT_Get_Glyph(face->glyph, &glyph);
|
||||||
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_SUBPIXELS, &bbox);
|
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_SUBPIXELS, &bbox);
|
||||||
if (horizontal_dir) {
|
if (horizontal_dir) {
|
||||||
x_max += glyph_info[i].x_advance;
|
x_position += glyph_info[i].x_advance;
|
||||||
|
|
||||||
if (i == count - 1) {
|
x_advanced = x_position;
|
||||||
// trim end gap from final glyph
|
|
||||||
int offset;
|
|
||||||
offset = glyph_info[i].x_advance -
|
offset = glyph_info[i].x_advance -
|
||||||
face->glyph->metrics.width -
|
face->glyph->metrics.width -
|
||||||
face->glyph->metrics.horiBearingX;
|
face->glyph->metrics.horiBearingX;
|
||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
x_max -= offset;
|
x_advanced -= offset;
|
||||||
}
|
if (x_advanced > x_max)
|
||||||
|
x_max = x_advanced;
|
||||||
|
|
||||||
bbox.yMax -= glyph_info[i].y_offset;
|
bbox.yMax += glyph_info[i].y_offset;
|
||||||
bbox.yMin -= glyph_info[i].y_offset;
|
bbox.yMin += glyph_info[i].y_offset;
|
||||||
if (bbox.yMax > y_max)
|
if (bbox.yMax > y_max)
|
||||||
y_max = bbox.yMax;
|
y_max = bbox.yMax;
|
||||||
if (bbox.yMin < y_min)
|
if (bbox.yMin < y_min)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user