From a77850564ae32c3b9ee289f1ebb9a5b8507025a0 Mon Sep 17 00:00:00 2001 From: shamsa Date: Tue, 16 Feb 2016 11:52:59 +0400 Subject: [PATCH] Fix gitsize function. --- PIL/ImageFont.py | 6 +- Tests/images/test_complex_unicode_text.png | Bin 1075 -> 1075 bytes _imagingft.c | 81 +++++++++++---------- 3 files changed, 46 insertions(+), 41 deletions(-) diff --git a/PIL/ImageFont.py b/PIL/ImageFont.py index 3f25a92b6..3aad8c076 100644 --- a/PIL/ImageFont.py +++ b/PIL/ImageFont.py @@ -136,8 +136,8 @@ class FreeTypeFont(object): def getmetrics(self): return self.font.ascent, self.font.descent - def getsize(self, text): - size, offset = self.font.getsize(text) + def getsize(self, text, direction=None, features=None): + size, offset = self.font.getsize(text, direction, features) return (size[0] + offset[0], size[1] + offset[1]) def getoffset(self, text): @@ -147,7 +147,7 @@ class FreeTypeFont(object): return self.getmask2(text, mode, direction=direction, features=features)[0] def getmask2(self, text, mode="", fill=Image.core.fill, direction=None, features=None): - size, offset = self.font.getsize(text) + size, offset = self.font.getsize(text, direction, features) im = fill("L", size, 0) self.font.render(text, im.id, mode == "1", direction, features) return im, offset diff --git a/Tests/images/test_complex_unicode_text.png b/Tests/images/test_complex_unicode_text.png index 565a2f9328df4c5dab8218c59c88360dfc7f40a3..dd4f6bf223fef6f5de91e9929494c109e1e85edf 100644 GIT binary patch delta 945 zcmV;i15W(22(t)~Hh**!8$&9?TNqLF5=B~s4;h6*Nf*Mvq*9_Ry5K`-NDqOC(L+xa zkwq5@!Sbn#1d&D;p$IY2%xH8n2Z=#PXPiYKMAL(Fat7zj%sDz9t?%dY?DhYzbvFBd z*4q254U!~D()q8Ymd4F68?G3wu}J?X<6$v;8JB9!WMF?5IaaQ*4! zu?VGqHPzI*8OFe$@arfINBaM%tq40{JSh0MUuHT0m&4DY4gP|el`VCv z!xz1@z>UxYog+It(%CZ$dO}zDICS)T8o4iQ4DI1?SjEZDJHlsS768-W&G1_&p(pGP z%SX`TM0hRiuSES6mc!c6+OLak;ni^Gi2u#}Je2TWI9N$?By0}f41B)2r2g|HjhYiX zLVuqHpat%Nr(h9GXz;jdumnojI@mHeFc+4=qm?OFI_InlCER<4vaNud&Q=uA1W!X( zI2PvCl|gE}H_m7gmat;&ngRG5 zK7lp8{8CT1QiJssVLR-C?#7O#7Co>BS_$F%UN%8{qsJqY(F018&;uD5={)ccaRKgE T5`#lM00000NkvXXu0mjf$pOm0 delta 945 zcmV;i15W(22(t)~Hh-K^Yz(OkZ(&5yOB87lK4cUMC0z&ulS+xQ=z65r1k0x`5=0tZgd)U5Go#UIa*!BwbjH~PLUej?4xYg|Gv^!~kLLIDc=r1L*E*a1 zKWpuM)&@zEBBmt&N4vg2%$6 zFa?god!;ivC`lu@13nJ@p$L1!D!8o9496hxxEJ912C~tdjgrczC$w^{uci z6yacaGh8y#(4=O20E*BTI>NC~ghf?aKF8qygqNRksDD5FP=67Q95n}ag(4gXtE#kl zB^0OpE?f(}p$PlKkx+#9y`j~)YCE}J0S?P_3fv|PN3w;U{ z;ggCsC!%&%iCPSY!$5d7Os<}G85H5Ep&!0faR)mMxMs&)|lb&EZdYt;Di&X-$P0a10if*btV$!q5d5 z!8HJE7;P)*MpzEJ!hV=gj%tN(LkAp($uPD2a(~87c%($vXy0T809V4Vp%earS>-Kt zYrP_~tD%h`$oTHsme z3&+B|hB8Ra_tqIL!Xm63`=}PU8lHroLJ@kyL-ltmoeLU#sdogE8hXLEuBa{HCTIiT zU-%5xmiVoaZl&gH1-fB3^f!AbwHtuF&s4%^r`F;R8C8&;uzLr1QgnJM`{X TlFJiF00000NkvXXu0mjf(Y3al diff --git a/_imagingft.c b/_imagingft.c index 201782143..ae570af51 100644 --- a/_imagingft.c +++ b/_imagingft.c @@ -205,60 +205,69 @@ font_getchar(PyObject* string, int index, FT_ULong* char_out) return 0; } +static size_t +text_layout(PyObject* string, FontObject* self, const char* dir, + PyObject *features ,GlyphInfo **glyph_info, int mask); + static PyObject* font_getsize(FontObject* self, PyObject* args) { int i, x, y_max, y_min; - FT_ULong ch; FT_Face face; int xoffset, yoffset; - FT_Bool kerning = FT_HAS_KERNING(self->face); - FT_UInt last_index = 0; + const char *dir = NULL; + size_t count; + GlyphInfo *glyph_info = NULL;; + PyObject *features = Py_None; /* calculate size and bearing for a given string */ PyObject* string; - if (!PyArg_ParseTuple(args, "O:getsize", &string)) + if (!PyArg_ParseTuple(args, "O|zO:getsize", &string, &dir, &features)) return NULL; -#if PY_VERSION_HEX >= 0x03000000 - if (!PyUnicode_Check(string)) { -#else - if (!PyUnicode_Check(string) && !PyString_Check(string)) { -#endif - PyErr_SetString(PyExc_TypeError, "expected string"); - return NULL; - } - face = NULL; xoffset = yoffset = 0; y_max = y_min = 0; - for (x = i = 0; font_getchar(string, i, &ch); i++) { + count = text_layout(string, self, dir, features, &glyph_info, 0); + if (count == 0) + return NULL; + + for (x = i = 0; i < count; i++) { int index, error; FT_BBox bbox; FT_Glyph glyph; face = self->face; - index = FT_Get_Char_Index(face, ch); - if (kerning && last_index && index) { - FT_Vector delta; - FT_Get_Kerning(self->face, last_index, index, ft_kerning_default, - &delta); - x += delta.x; - } - - /* Note: bitmap fonts within ttf fonts do not work, see #891/pr#960 - * Yifu Yu, 2014-10-15 - */ + index = glyph_info[i].index; + /* Note: bitmap fonts within ttf fonts do not work, see #891/pr#960 + * Yifu Yu, 2014-10-15 + */ error = FT_Load_Glyph(face, index, FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP); if (error) return geterror(error); - if (i == 0) + + if (i == 0 && face->glyph->metrics.horiBearingX < 0) { xoffset = face->glyph->metrics.horiBearingX; - x += face->glyph->metrics.horiAdvance; + x -= xoffset; + } + + x += glyph_info[i].x_advance; + + if (i == count - 1) + { + int offset; + offset = glyph_info[i].x_advance - + face->glyph->metrics.width - + face->glyph->metrics.horiBearingX; + if (offset < 0) + x -= offset; + } FT_Get_Glyph(face->glyph, &glyph); FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_SUBPIXELS, &bbox); + bbox.yMax -= glyph_info[i].y_offset; + bbox.yMin -= glyph_info[i].y_offset; if (bbox.yMax > y_max) y_max = bbox.yMax; if (bbox.yMin < y_min) @@ -268,23 +277,17 @@ font_getsize(FontObject* self, PyObject* args) if (face->glyph->metrics.horiBearingY > yoffset) yoffset = face->glyph->metrics.horiBearingY; - last_index = index; + //last_index = index; FT_Done_Glyph(glyph); } if (face) { - int offset; + /* left bearing */ if (xoffset < 0) x -= xoffset; else xoffset = 0; - /* right bearing */ - offset = face->glyph->metrics.horiAdvance - - face->glyph->metrics.width - - face->glyph->metrics.horiBearingX; - if (offset < 0) - x -= offset; /* difference between the font ascender and the distance of * the baseline from the top */ yoffset = PIXEL(self->face->size->metrics.ascender - yoffset); @@ -323,7 +326,7 @@ font_getabc(FontObject* self, PyObject* args) int index, error; face = self->face; index = FT_Get_Char_Index(face, ch); - /* Note: bitmap fonts within ttf fonts do not work, see #891/pr#960 */ + /* Note: bitmap fonts within ttf fonts do not work, see #891/pr#960 */ error = FT_Load_Glyph(face, index, FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP); if (error) return geterror(error); @@ -589,15 +592,15 @@ font_render(FontObject* self, PyObject* args) for (x = i = 0; i < count; i++) { if (i == 0 && self->face->glyph->metrics.horiBearingX < 0) x = -self->face->glyph->metrics.horiBearingX; - index = glyph_info[i].index; + index = glyph_info[i].index; error = FT_Load_Glyph(self->face, index, load_flags); if (error) return geterror(error); if (i == 0 && self->face->glyph->metrics.horiBearingX < 0) { x = -self->face->glyph->metrics.horiBearingX; - } + } glyph = self->face->glyph; @@ -638,6 +641,7 @@ font_render(FontObject* self, PyObject* args) yy -= PIXEL(glyph_info[i].y_offset); if (yy >= 0 && yy < im->ysize) { /* blend this glyph into the buffer */ + int i; unsigned char *target = im->image8[yy] + xx; for (i = x0; i < x1; i++) { @@ -650,6 +654,7 @@ font_render(FontObject* self, PyObject* args) } x += glyph_info[i].x_advance; } + PyMem_Del(glyph_info); Py_RETURN_NONE; }