From bc0bf5efea357a18c8f10a0c5768e837891b808e Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 10 Apr 2023 18:47:58 +1000 Subject: [PATCH] Preserve line spacing backwards compatibility --- Tests/images/imagedraw_stroke_multiline.png | Bin 4059 -> 4061 bytes Tests/test_imagedraw.py | 4 ++-- src/PIL/ImageDraw.py | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Tests/images/imagedraw_stroke_multiline.png b/Tests/images/imagedraw_stroke_multiline.png index c290fc0568e5c4b40299a208cde7d0d760077fd0..fc5e07c8679d5aa12a1d95152ea6d2542f169697 100644 GIT binary patch delta 3990 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 diff --git a/Tests/test_imagedraw.py b/Tests/test_imagedraw.py index 17ee75dfa..7ffd7969d 100644 --- a/Tests/test_imagedraw.py +++ b/Tests/test_imagedraw.py @@ -1220,8 +1220,8 @@ def test_textbbox_stroke(): # Act / Assert assert draw.textbbox((2, 2), "A", font, stroke_width=2) == (0, 4, 16, 20) assert draw.textbbox((2, 2), "A", font, stroke_width=4) == (-2, 2, 18, 22) - assert draw.textbbox((2, 2), "ABC\nAaaa", font, stroke_width=2) == (0, 4, 52, 42) - assert draw.textbbox((2, 2), "ABC\nAaaa", font, stroke_width=4) == (-2, 2, 54, 46) + assert draw.textbbox((2, 2), "ABC\nAaaa", font, stroke_width=2) == (0, 4, 52, 44) + assert draw.textbbox((2, 2), "ABC\nAaaa", font, stroke_width=4) == (-2, 2, 54, 50) @skip_unless_feature("freetype2") diff --git a/src/PIL/ImageDraw.py b/src/PIL/ImageDraw.py index c16ff28cc..e9ccf8041 100644 --- a/src/PIL/ImageDraw.py +++ b/src/PIL/ImageDraw.py @@ -431,7 +431,11 @@ class ImageDraw: return text.split(split_character) def _multiline_spacing(self, font, spacing, stroke_width): - return self.textbbox((0, 0), "A", font, stroke_width=stroke_width)[3] + spacing + return ( + self.textbbox((0, 0), "A", font, stroke_width=stroke_width)[3] + + stroke_width + + spacing + ) def text( self,