@@ -690,8 +690,7 @@ def _prepare_multiline_text(
690
690
font_size : float | None ,
691
691
) -> tuple [
692
692
ImageFont .ImageFont | ImageFont .FreeTypeFont | ImageFont .TransposedFont ,
693
- str ,
694
- list [tuple [tuple [float , float ], AnyStr ]],
693
+ list [tuple [tuple [float , float ], str , AnyStr ]],
695
694
]:
696
695
if direction == "ttb" :
697
696
msg = "ttb direction is unsupported for multiline text"
@@ -741,13 +740,7 @@ def _prepare_multiline_text(
741
740
left = xy [0 ]
742
741
width_difference = max_width - widths [idx ]
743
742
744
- # first align left by anchor
745
- if anchor [0 ] == "m" :
746
- left -= width_difference / 2.0
747
- elif anchor [0 ] == "r" :
748
- left -= width_difference
749
-
750
- # then align by align parameter
743
+ # align by align parameter
751
744
if align in ("left" , "justify" ):
752
745
pass
753
746
elif align == "center" :
@@ -758,29 +751,43 @@ def _prepare_multiline_text(
758
751
msg = 'align must be "left", "center", "right" or "justify"'
759
752
raise ValueError (msg )
760
753
761
- if align == "justify" and width_difference != 0 :
754
+ if align == "justify" and width_difference != 0 and idx != len ( lines ) - 1 :
762
755
words = line .split (" " if isinstance (text , str ) else b" " )
763
- word_widths = [
764
- self .textlength (
765
- word ,
766
- font ,
767
- direction = direction ,
768
- features = features ,
769
- language = language ,
770
- embedded_color = embedded_color ,
771
- )
772
- for word in words
773
- ]
774
- width_difference = max_width - sum (word_widths )
775
- for i , word in enumerate (words ):
776
- parts .append (((left , top ), word ))
777
- left += word_widths [i ] + width_difference / (len (words ) - 1 )
778
- else :
779
- parts .append (((left , top ), line ))
756
+ if len (words ) > 1 :
757
+ # align left by anchor
758
+ if anchor [0 ] == "m" :
759
+ left -= max_width / 2.0
760
+ elif anchor [0 ] == "r" :
761
+ left -= max_width
762
+
763
+ word_widths = [
764
+ self .textlength (
765
+ word ,
766
+ font ,
767
+ direction = direction ,
768
+ features = features ,
769
+ language = language ,
770
+ embedded_color = embedded_color ,
771
+ )
772
+ for word in words
773
+ ]
774
+ word_anchor = "l" + anchor [1 ]
775
+ width_difference = max_width - sum (word_widths )
776
+ for i , word in enumerate (words ):
777
+ parts .append (((left , top ), word_anchor , word ))
778
+ left += word_widths [i ] + width_difference / (len (words ) - 1 )
779
+ top += line_spacing
780
+ continue
780
781
782
+ # align left by anchor
783
+ if anchor [0 ] == "m" :
784
+ left -= width_difference / 2.0
785
+ elif anchor [0 ] == "r" :
786
+ left -= width_difference
787
+ parts .append (((left , top ), anchor , line ))
781
788
top += line_spacing
782
789
783
- return font , anchor , parts
790
+ return font , parts
784
791
785
792
def multiline_text (
786
793
self ,
@@ -805,7 +812,7 @@ def multiline_text(
805
812
* ,
806
813
font_size : float | None = None ,
807
814
) -> None :
808
- font , anchor , lines = self ._prepare_multiline_text (
815
+ font , lines = self ._prepare_multiline_text (
809
816
xy ,
810
817
text ,
811
818
font ,
@@ -820,7 +827,7 @@ def multiline_text(
820
827
font_size ,
821
828
)
822
829
823
- for xy , line in lines :
830
+ for xy , anchor , line in lines :
824
831
self .text (
825
832
xy ,
826
833
line ,
@@ -935,7 +942,7 @@ def multiline_textbbox(
935
942
* ,
936
943
font_size : float | None = None ,
937
944
) -> tuple [float , float , float , float ]:
938
- font , anchor , lines = self ._prepare_multiline_text (
945
+ font , lines = self ._prepare_multiline_text (
939
946
xy ,
940
947
text ,
941
948
font ,
@@ -952,7 +959,7 @@ def multiline_textbbox(
952
959
953
960
bbox : tuple [float , float , float , float ] | None = None
954
961
955
- for xy , line in lines :
962
+ for xy , anchor , line in lines :
956
963
bbox_line = self .textbbox (
957
964
xy ,
958
965
line ,
0 commit comments