From cccc07269ae60226f0bb6475970d6fab255538b4 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Thu, 17 Apr 2025 19:23:24 +1000 Subject: [PATCH] Do not justify a single word --- .../multiline_text_justify_single_word.png | Bin 0 -> 2436 bytes Tests/test_imagefont.py | 12 ++++++ src/PIL/ImageDraw.py | 36 +++++++++--------- 3 files changed, 31 insertions(+), 17 deletions(-) create mode 100644 Tests/images/multiline_text_justify_single_word.png diff --git a/Tests/images/multiline_text_justify_single_word.png b/Tests/images/multiline_text_justify_single_word.png new file mode 100644 index 0000000000000000000000000000000000000000..e124e91f5e34d64b002b06f5c66fc72ddb80a31c GIT binary patch literal 2436 zcmY*beLRzEA0J0yB(}_ud7mN7_>h-jBJ%#S6r0e=A!LqpWpoYZ?RWh!4&n+g#Fg+L<5j4t5r#GU+=GKvJekb!n|JNhWUPt9 zc^|#kHd}rgFLU3^f{E8JRg_;!n-Rw$$N!R6_4e#U2Z5kCJ=I%2#>%{yn3%dzS#+Wu zis~bqn=&_Q5o#_&bJF&+0JS885_d(Tw!_WYY<6l#W@_pK4rhf=fsPINA(y8FMck}S zEgcDgW>S}9iBZ(Fz{iY5M4o*(m+Psr&3F;BPU)jU z;U5t#$D5vHtlf=C;8YAqOpJ~7g)J>DWHOmTq0~}-I6$6o4n^Gxta3SBg(~aU(b3uY zJ25soS`USKo~mC^P|#8WL^uFb>PV@ptDBjbvGmt;v+rDfCl+%v){>kRCteYk@$X zJP80N#BWA{m6X_PUO7ikj!VkjnfPPJDkFNu1L9(dQ~Lbn%a>_8PmZt7`up!$9V+xN zu;$$5LW|?R>+XNupL?Mj_8NJIt0^9L2dZ4}3qO^VsO7r7|NPn6s*cT8BgasEVq;?1 zXWrVmRBbOy0y~IVpGDS5wB(}2f>}ismC<-xv@-Y7Mi@cgj=lSnqLNZ#LP7_k)42m{C8iFG~*YPyTz|nw=f0 z3#`)7v9r1P%+#|RV_pCbMMZ%mlGRn7K7?YcB^|Eyoeh41n4}Ivb#<#~v<98q<>i_h z8gaJ}QBhG>+;R1<73E}e-4s+*=A}~qz(B#XS-KLU=nWuqEvW76^Qaex86y`CGzxrj;ip{bdf)!8A#n%l+2s!(YD zEkIO31LWL`7#o`oqNN=VlX>*eOrBth?s7@XR3H$<#l|ungGm+a_4V;nknK7Z zZ=(>vO5)-qBO@b&gF)xduXJD9up>=0={VTiYrx@vIyieZXVp%qVd-=_-b~oj(=$Ab z!D2T7YI}DT7Wy7LRu+7bf71FYF9r>75QiHWpF4?-9YCb8cvDwb zZb!%Z#FGpg8=J<)M!=#)?ZQQp(}d2`7a9G%=OeW|Fm*A zItNp70_v6IWN#dXs;dh{BGK4bLK9-Yib-joC9ypRA4w#(6O&J$Hod4B@jX_yr7v=s zl)(N`aMPYN5l!$m8qTX!ABWHHptd09x@P{H5+5Ibbf>A)16(gG>ZLWq8|rIocXdS; z_kSc>YGeeXQ!M}4$@o)lhpLQ>%*&TAftoQoI;x_gl4M6fmf}>;%?|2IqZ{$}s?B-W zp8huv6W_4*>bl^=!VHe)x($ww&P-3AYGN>%%%!DNts7+CrWrVr_gX!xkllq?(S~+y@-R3j!WyANv;eA<2h9C z0FTED3kzHB#Jn?nydSHOpPvudqN#w-KhQ21zApiC2&{KyWyOq|keT_owl;Pm3xpF8 zoqt)9JMz5TCQkJWTG{Y-e`ZJ{TKUb$NRwOE=#y+{i`}<9TmDbST5fJu=5S>GwU_y> z{HBbjPAM|5S(_|_lH)|;RSjcsxIasdjWoo%TL)g5hoCeviZ9 zXjq+SWwWjCL7$HO_%327OP&>cSXGXFoERKzZEI@;D^v?abtZ#mt}AY(=bvyjed-+E zyrHKvyHYCqXQ^0h{`&Rn3(i?*$Rl$myJ#j{Nm5dh@>QNO5(%MrKq%9H|6N{E!uIK| zZzi<;My1AV)&Ldi None: + im = Image.new("RGB", (185, 65)) + draw = ImageDraw.Draw(im) + draw.multiline_text( + (0, 0), "hey you\nyou are awesome\nthis", font=font, align="justify" + ) + + assert_image_equal_tofile(im, "Tests/images/multiline_text_justify_single_word.png") + + def test_unknown_align(font: ImageFont.FreeTypeFont) -> None: im = Image.new(mode="RGB", size=(300, 100)) draw = ImageDraw.Draw(im) diff --git a/src/PIL/ImageDraw.py b/src/PIL/ImageDraw.py index e6c7b0298..e865f4516 100644 --- a/src/PIL/ImageDraw.py +++ b/src/PIL/ImageDraw.py @@ -772,24 +772,26 @@ class ImageDraw: if align == "justify" and width_difference != 0: words = line.split(" " if isinstance(text, str) else b" ") - word_widths = [ - self.textlength( - word, - font, - direction=direction, - features=features, - language=language, - embedded_color=embedded_color, - ) - for word in words - ] - width_difference = max_width - sum(word_widths) - for i, word in enumerate(words): - parts.append(((left, top), word)) - left += word_widths[i] + width_difference / (len(words) - 1) - else: - parts.append(((left, top), line)) + if len(words) > 1: + word_widths = [ + self.textlength( + word, + font, + direction=direction, + features=features, + language=language, + embedded_color=embedded_color, + ) + for word in words + ] + width_difference = max_width - sum(word_widths) + for i, word in enumerate(words): + parts.append(((left, top), word)) + left += word_widths[i] + width_difference / (len(words) - 1) + top += line_spacing + continue + parts.append(((left, top), line)) top += line_spacing return font, anchor, parts