Skip to content

Commit bc05a88

Browse files
committed
Anchor left when justifying words
1 parent b955cee commit bc05a88

File tree

4 files changed

+32
-25
lines changed

4 files changed

+32
-25
lines changed
11 KB
Loading
Binary file not shown.

Tests/test_imagefont.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -267,19 +267,21 @@ def test_render_multiline_text_align(
267267
assert_image_similar_tofile(im, f"Tests/images/multiline_text{ext}.png", 0.01)
268268

269269

270-
def test_render_multiline_text_align_justify_last_line(
270+
def test_render_multiline_text_justify_anchor(
271271
font: ImageFont.FreeTypeFont,
272272
) -> None:
273-
im = Image.new("RGB", (280, 60))
273+
im = Image.new("RGB", (280, 240))
274274
draw = ImageDraw.Draw(im)
275-
draw.multiline_text(
276-
(0, 0),
277-
"hey you you are awesome\nthis\nlooks awkward",
278-
font=font,
279-
align="justify",
280-
)
275+
for xy, anchor in (((0, 0), "la"), ((140, 80), "ma"), ((280, 160), "ra")):
276+
draw.multiline_text(
277+
xy,
278+
"hey you you are awesome\nthis looks awkward\nthis\nlooks awkward",
279+
font=font,
280+
anchor=anchor,
281+
align="justify",
282+
)
281283

282-
assert_image_equal_tofile(im, "Tests/images/multiline_text_justify_last_line.png")
284+
assert_image_equal_tofile(im, "Tests/images/multiline_text_justify_anchor.png")
283285

284286

285287
def test_unknown_align(font: ImageFont.FreeTypeFont) -> None:

src/PIL/ImageDraw.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -702,8 +702,7 @@ def _prepare_multiline_text(
702702
font_size: float | None,
703703
) -> tuple[
704704
ImageFont.ImageFont | ImageFont.FreeTypeFont | ImageFont.TransposedFont,
705-
str,
706-
list[tuple[tuple[float, float], AnyStr]],
705+
list[tuple[tuple[float, float], str, AnyStr]],
707706
]:
708707
if direction == "ttb":
709708
msg = "ttb direction is unsupported for multiline text"
@@ -753,13 +752,7 @@ def _prepare_multiline_text(
753752
left = xy[0]
754753
width_difference = max_width - widths[idx]
755754

756-
# first align left by anchor
757-
if anchor[0] == "m":
758-
left -= width_difference / 2.0
759-
elif anchor[0] == "r":
760-
left -= width_difference
761-
762-
# then align by align parameter
755+
# align by align parameter
763756
if align in ("left", "justify"):
764757
pass
765758
elif align == "center":
@@ -773,6 +766,12 @@ def _prepare_multiline_text(
773766
if align == "justify" and width_difference != 0 and idx != len(lines) - 1:
774767
words = line.split(" " if isinstance(text, str) else b" ")
775768
if len(words) > 1:
769+
# align left by anchor
770+
if anchor[0] == "m":
771+
left -= max_width / 2.0
772+
elif anchor[0] == "r":
773+
left -= max_width
774+
776775
word_widths = [
777776
self.textlength(
778777
word,
@@ -784,17 +783,23 @@ def _prepare_multiline_text(
784783
)
785784
for word in words
786785
]
786+
word_anchor = "l" + anchor[1]
787787
width_difference = max_width - sum(word_widths)
788788
for i, word in enumerate(words):
789-
parts.append(((left, top), word))
789+
parts.append(((left, top), word_anchor, word))
790790
left += word_widths[i] + width_difference / (len(words) - 1)
791791
top += line_spacing
792792
continue
793793

794-
parts.append(((left, top), line))
794+
# align left by anchor
795+
if anchor[0] == "m":
796+
left -= width_difference / 2.0
797+
elif anchor[0] == "r":
798+
left -= width_difference
799+
parts.append(((left, top), anchor, line))
795800
top += line_spacing
796801

797-
return font, anchor, parts
802+
return font, parts
798803

799804
def multiline_text(
800805
self,
@@ -819,7 +824,7 @@ def multiline_text(
819824
*,
820825
font_size: float | None = None,
821826
) -> None:
822-
font, anchor, lines = self._prepare_multiline_text(
827+
font, lines = self._prepare_multiline_text(
823828
xy,
824829
text,
825830
font,
@@ -834,7 +839,7 @@ def multiline_text(
834839
font_size,
835840
)
836841

837-
for xy, line in lines:
842+
for xy, anchor, line in lines:
838843
self.text(
839844
xy,
840845
line,
@@ -949,7 +954,7 @@ def multiline_textbbox(
949954
*,
950955
font_size: float | None = None,
951956
) -> tuple[float, float, float, float]:
952-
font, anchor, lines = self._prepare_multiline_text(
957+
font, lines = self._prepare_multiline_text(
953958
xy,
954959
text,
955960
font,
@@ -966,7 +971,7 @@ def multiline_textbbox(
966971

967972
bbox: tuple[float, float, float, float] | None = None
968973

969-
for xy, line in lines:
974+
for xy, anchor, line in lines:
970975
bbox_line = self.textbbox(
971976
xy,
972977
line,

0 commit comments

Comments
 (0)