From 25b39de5b700e5e14727b431645196628547b950 Mon Sep 17 00:00:00 2001 From: paddywwoof Date: Thu, 19 Sep 2013 15:30:08 +0100 Subject: [PATCH 1/4] ImageColor defaults to alpha = 255 in only rgb specified for RGBA mode --- PIL/ImageColor.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PIL/ImageColor.py b/PIL/ImageColor.py index 2a190fc66..86f221adc 100644 --- a/PIL/ImageColor.py +++ b/PIL/ImageColor.py @@ -102,6 +102,8 @@ def getcolor(color, mode): if mode == "RGB": return color if mode == "RGBA": + if len(color) == 3: + color = (color + (255,)) r, g, b, a = color return r, g, b, a if Image.getmodebase(mode) == "L": From 02855a86c07afadf380c018152197f6b6dbae5c6 Mon Sep 17 00:00:00 2001 From: paddywwoof Date: Fri, 20 Sep 2013 14:02:40 +0100 Subject: [PATCH 2/4] hopefully this uses a reasonable y offset --- PIL/ImageFont.py | 5 ++++- _imagingft.c | 15 +++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/PIL/ImageFont.py b/PIL/ImageFont.py index 2cb9c41d2..826b37d5c 100644 --- a/PIL/ImageFont.py +++ b/PIL/ImageFont.py @@ -157,6 +157,9 @@ class FreeTypeFont: def getsize(self, text): return self.font.getsize(text)[0] + def getoffset(self, text): + return self.font.getsize(text)[1] + def getmask(self, text, mode=""): return self.getmask2(text, mode)[0] @@ -183,7 +186,7 @@ class TransposedFont: self.orientation = orientation # any 'transpose' argument, or None def getsize(self, text): - w, h = self.font.getsize(text) + w, h = self.font.getsize(text)[0] if self.orientation in (Image.ROTATE_90, Image.ROTATE_270): return h, w return w, h diff --git a/_imagingft.c b/_imagingft.c index 9dcc83183..47d50bdca 100644 --- a/_imagingft.c +++ b/_imagingft.c @@ -183,7 +183,7 @@ font_getsize(FontObject* self, PyObject* args) int i, x, y_max, y_min; FT_ULong ch; FT_Face face; - int xoffset; + int xoffset, yoffset; FT_Bool kerning = FT_HAS_KERNING(self->face); FT_UInt last_index = 0; @@ -203,7 +203,7 @@ font_getsize(FontObject* self, PyObject* args) } face = NULL; - xoffset = 0; + xoffset = yoffset = 0; y_max = y_min = 0; for (x = i = 0; font_getchar(string, i, &ch); i++) { @@ -231,7 +231,11 @@ font_getsize(FontObject* self, PyObject* args) y_max = bbox.yMax; if (bbox.yMin < y_min) y_min = bbox.yMin; - + + /* find max distance of baseline from top */ + if (face->glyph->metrics.horiBearingY > yoffset) + yoffset = face->glyph->metrics.horiBearingY; + last_index = index; } @@ -248,12 +252,15 @@ font_getsize(FontObject* self, PyObject* args) 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); } return Py_BuildValue( "(ii)(ii)", PIXEL(x), PIXEL(y_max - y_min), - PIXEL(xoffset), 0 + PIXEL(xoffset), yoffset ); } From 35c9f59c3838c797ede6b5765aeb5f6d8c0921e2 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Tue, 24 Sep 2013 14:23:17 -0700 Subject: [PATCH 3/4] testcase for multiline text spacing --- Tests/images/multiline_text.png | Bin 0 -> 2843 bytes Tests/test_imagefont.py | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 Tests/images/multiline_text.png diff --git a/Tests/images/multiline_text.png b/Tests/images/multiline_text.png new file mode 100644 index 0000000000000000000000000000000000000000..ff1308c5ef277048d26abec36dd76610e8fbf3fe GIT binary patch literal 2843 zcmb_e_g9ly6Go6;R1lFa$^ueXno=akEJ(nFq7Vd;E+AD5MOtt*f)N8sQ33%Ll=ji2 z1?g?0OGpS(gwP2HBF&JH2r;m)>)CVm5BPqWcg~sn-g#!`nVE}ru(K8ykrUzJ;Ssli zSYGAfIiwBfenPx}Z1Bx}$-^T;v$4G7bPu;N6AZZ)t|0i8OxC&aNvC4;Pw)WoimQ{K zmCph1FPfrpQdn^tkta27dfOOjezlCq=Z2c8xeJ=AT0PnWw~NGIFz{;rrH7;IqU*X> z4rtxG%9LeRNI@i*gY?+IG1g;|E4YjK8>B=jG~ky6dR#m2lw+(l4w;kv$lqYkr3mxojpE535cqs$C{#9w4t%FoAwJzA*gcf%f!U> z&5wAzG5D{cp`q5OwH%|my1FhT_cW@psp-SGB{luJ_G}BH?DDH~Sg2ZNMQ0~+yym7) zT~4SM$F=#@tA|G)uxIDdLMkOCCF=GCViFQ8I^6~W2@DC**3g*8_fsgf6&0=>aXU-> znZJR-`uh5&W@b{7k`n?~D;ir`Of)nebF{Hg)|W9YEcCLc7z`wdeqB{n1z-2xq@)X1KqNC)_Omg{0VPkZx6b=^tf{8!iKt*R%LztRn6?XQ;?Ej>vW}vJa5Tf<-XO_ zrt)%)vuFG9FdLix`db4N1Ys$)#>PfyfjQRocq$<(D(YG(G@?nVjC)cnIVb1jl=?dY zA!4rH=jZP`3w^ z&*CGN)|0jI+LfiH36F%gF=u3f*n^r(b#y{^w?AEeRaaX}=^!ewuerM?u-08?xi`YY zx7yp=X*8c`3^hbTOl%47TJMLB-{JZ0Vd(M{hr_kDwk|C#{qe^sEcAq|EEbEc7z>io zzTO@0tIV0EPR(-Xi z)V{FBLF0wajp&8mN6E=#Tid9p9ro57OfA!{%nY#%wX{Ud zScr;<5Q)Ugo_PB@*MP*qKh z(j4-ip7~dJ`6=bB7CUJM2M2TZ_K^GEsbgbNo6{{enQHXOlVSpRMt662adC02XO|r2 zT~^ldFoX9k7aoi@gw3=T6{$>V0hzQjG0)XawpQhLlT9}=k{rvet(8VLl z7VWVNe?Pz1?z-uZAHR*>kYk@5#)*O<2n1uYDOg&>DlBZX%)T&Z&d=Z9|4U@+TuefD zqEf-?>1iLpW%A0KbVGLo)zadK$rRA&G8@81i|WAE-US3{@p zEp8NmcD%g2Z-aUH_&6L6)hZWp$w2s#sl_SPBmI#r@$4{1N5?yN-T-7sOBNofH zq=SN^!((FvygKgfDSdO(K<0bF!^u#Y`*ai_BL2~ShsykH+&h1=njhHF_am3j?|!47 zVK}my(`fHD)6FQgRECy9u)xEf2tJqe@pNU-WyiGOck}N1Xg!&q#%p#*1l1O{l)!fi zJR4SAE|eZFMEMG54(a|h^LdydDv7oyx=IZM20}X*q zTUuH=I_l(-PC8H~XTND|WCE+Or>Dol!a`VB7=yv^^Ye#Ae!lP%9MV1JAU8hU$sM-LoL=(5~grVjnU zyBPPj50k}4eEaI%-G)vqY=Z6W)>%1}`#)B9foTucul4j7cnF?PK-c zUffi<=*Q3OE9K_$#N2$=8K+qa@Dzy!p^u|2N#QW-IO1F&Nv&u^O#1wUVyar|BYm?J zS+MpAK>>kIBsUjkvn=V?g(5Z-RZ(w)z@NBG7ArX=g#ibIucU-;lUwLkT!gTZaK8V4 zBA-?%h2?!59c}a{%gx?-u>R5^);P<^Y{R;|y%6Z~D=&5F@DtL~0Bpv5&qH7YK6`dl zS-G$Uu@W}d$z2^OYY3qD%L^F^qZ|H<>%1id@)%zE=@)0wdQaXT$y{$#F4{%{9m}oYrtL){s!ysj86an literal 0 HcmV?d00001 diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index fad7970cc..dd74ef2cb 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -67,3 +67,21 @@ def test_render_equal(): assert_image_equal(img_path, img_filelike) _clean() + + +def test_render_multiline(): + im = Image.new(mode='RGB', size=(300,100)) + ttf = ImageFont.truetype(font_path, font_size) + draw = ImageDraw.Draw(im) + line_spacing = draw.textsize('A', font=ttf)[1] + 8 + lines = ['hey you', 'you are awesome', 'this looks awkward'] + y = 0 + for line in lines: + draw.text((0, y), line, font=ttf) + y += line_spacing + + target = 'Tests/images/multiline_text.png' + target_img = Image.open(target) + + assert_image_equal(im, target_img) + From ae6eb8733ab23b96f6c0f98de53d13f7f7100ba1 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Tue, 24 Sep 2013 14:23:43 -0700 Subject: [PATCH 4/4] actually cleaning --- Tests/test_imagefont.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index dd74ef2cb..838075c4c 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -35,7 +35,7 @@ def test_font_with_filelike(): #shared_bytes = _font_as_bytes() #assert_no_exception(lambda: _render(shared_bytes)) #assert_exception(Exception, lambda: _render(shared_bytes)) - _clean + _clean() def test_font_with_open_file(): with open(font_path, 'rb') as f: