diff --git a/Tests/fonts/LICENSE.txt b/Tests/fonts/LICENSE.txt index b9488cb94..528eed9ef 100644 --- a/Tests/fonts/LICENSE.txt +++ b/Tests/fonts/LICENSE.txt @@ -1,5 +1,6 @@ NotoNastaliqUrdu-Regular.ttf and NotoSansSymbols-Regular.ttf, from https://github.com/googlei18n/noto-fonts +NotoSans-Regular.ttf, from https://www.google.com/get/noto/ NotoSansJP-Thin.otf, from https://www.google.com/get/noto/help/cjk/ AdobeVFPrototype.ttf, from https://github.com/adobe-fonts/adobe-variable-font-prototype TINY5x3GX.ttf, from http://velvetyne.fr/fonts/tiny diff --git a/Tests/fonts/NotoSans-Regular.ttf b/Tests/fonts/NotoSans-Regular.ttf new file mode 100644 index 000000000..a1b8994ed Binary files /dev/null and b/Tests/fonts/NotoSans-Regular.ttf differ diff --git a/Tests/images/test_anchor_quick_ls.png b/Tests/images/test_anchor_quick_ls.png new file mode 100644 index 000000000..df3b63e33 Binary files /dev/null and b/Tests/images/test_anchor_quick_ls.png differ diff --git a/Tests/images/test_anchor_quick_ma.png b/Tests/images/test_anchor_quick_ma.png new file mode 100644 index 000000000..5ee4abc62 Binary files /dev/null and b/Tests/images/test_anchor_quick_ma.png differ diff --git a/Tests/images/test_anchor_quick_mb.png b/Tests/images/test_anchor_quick_mb.png new file mode 100644 index 000000000..5a5177ac0 Binary files /dev/null and b/Tests/images/test_anchor_quick_mb.png differ diff --git a/Tests/images/test_anchor_quick_md.png b/Tests/images/test_anchor_quick_md.png new file mode 100644 index 000000000..7f9d4638f Binary files /dev/null and b/Tests/images/test_anchor_quick_md.png differ diff --git a/Tests/images/test_anchor_quick_mm.png b/Tests/images/test_anchor_quick_mm.png new file mode 100644 index 000000000..f85d61424 Binary files /dev/null and b/Tests/images/test_anchor_quick_mm.png differ diff --git a/Tests/images/test_anchor_quick_ms.png b/Tests/images/test_anchor_quick_ms.png new file mode 100644 index 000000000..ad600c9cf Binary files /dev/null and b/Tests/images/test_anchor_quick_ms.png differ diff --git a/Tests/images/test_anchor_quick_mt.png b/Tests/images/test_anchor_quick_mt.png new file mode 100644 index 000000000..a7c8bd1a8 Binary files /dev/null and b/Tests/images/test_anchor_quick_mt.png differ diff --git a/Tests/images/test_anchor_quick_rs.png b/Tests/images/test_anchor_quick_rs.png new file mode 100644 index 000000000..f5a533bbf Binary files /dev/null and b/Tests/images/test_anchor_quick_rs.png differ diff --git a/Tests/images/test_anchor_ttb_f_lt.png b/Tests/images/test_anchor_ttb_f_lt.png new file mode 100644 index 000000000..c38aa3c7f Binary files /dev/null and b/Tests/images/test_anchor_ttb_f_lt.png differ diff --git a/Tests/images/test_anchor_ttb_f_mm.png b/Tests/images/test_anchor_ttb_f_mm.png new file mode 100644 index 000000000..946d04e8b Binary files /dev/null and b/Tests/images/test_anchor_ttb_f_mm.png differ diff --git a/Tests/images/test_anchor_ttb_f_rb.png b/Tests/images/test_anchor_ttb_f_rb.png new file mode 100644 index 000000000..c307b395b Binary files /dev/null and b/Tests/images/test_anchor_ttb_f_rb.png differ diff --git a/Tests/images/test_anchor_ttb_f_sm.png b/Tests/images/test_anchor_ttb_f_sm.png new file mode 100644 index 000000000..5f55a6842 Binary files /dev/null and b/Tests/images/test_anchor_ttb_f_sm.png differ diff --git a/Tests/images/test_arabictext_features.png b/Tests/images/test_arabictext_features.png index 9bfa5a931..cb9a07443 100644 Binary files a/Tests/images/test_arabictext_features.png and b/Tests/images/test_arabictext_features.png differ diff --git a/Tests/images/test_combine_caron.png b/Tests/images/test_combine_caron.png new file mode 100644 index 000000000..e33dc2be6 Binary files /dev/null and b/Tests/images/test_combine_caron.png differ diff --git a/Tests/images/test_combine_caron_below.png b/Tests/images/test_combine_caron_below.png new file mode 100644 index 000000000..2c14c8f33 Binary files /dev/null and b/Tests/images/test_combine_caron_below.png differ diff --git a/Tests/images/test_combine_caron_below_lb.png b/Tests/images/test_combine_caron_below_lb.png new file mode 100644 index 000000000..0d285a1e6 Binary files /dev/null and b/Tests/images/test_combine_caron_below_lb.png differ diff --git a/Tests/images/test_combine_caron_below_ld.png b/Tests/images/test_combine_caron_below_ld.png new file mode 100644 index 000000000..bb7172307 Binary files /dev/null and b/Tests/images/test_combine_caron_below_ld.png differ diff --git a/Tests/images/test_combine_caron_below_ls.png b/Tests/images/test_combine_caron_below_ls.png new file mode 100644 index 000000000..73e339f6f Binary files /dev/null and b/Tests/images/test_combine_caron_below_ls.png differ diff --git a/Tests/images/test_combine_caron_below_ttb.png b/Tests/images/test_combine_caron_below_ttb.png new file mode 100644 index 000000000..8a5e966bf Binary files /dev/null and b/Tests/images/test_combine_caron_below_ttb.png differ diff --git a/Tests/images/test_combine_caron_below_ttb_lb.png b/Tests/images/test_combine_caron_below_ttb_lb.png new file mode 100644 index 000000000..9893a1ebe Binary files /dev/null and b/Tests/images/test_combine_caron_below_ttb_lb.png differ diff --git a/Tests/images/test_combine_caron_la.png b/Tests/images/test_combine_caron_la.png new file mode 100644 index 000000000..e33dc2be6 Binary files /dev/null and b/Tests/images/test_combine_caron_la.png differ diff --git a/Tests/images/test_combine_caron_ls.png b/Tests/images/test_combine_caron_ls.png new file mode 100644 index 000000000..10542305b Binary files /dev/null and b/Tests/images/test_combine_caron_ls.png differ diff --git a/Tests/images/test_combine_caron_lt.png b/Tests/images/test_combine_caron_lt.png new file mode 100644 index 000000000..732601ed4 Binary files /dev/null and b/Tests/images/test_combine_caron_lt.png differ diff --git a/Tests/images/test_combine_caron_ttb.png b/Tests/images/test_combine_caron_ttb.png new file mode 100644 index 000000000..1ac181afb Binary files /dev/null and b/Tests/images/test_combine_caron_ttb.png differ diff --git a/Tests/images/test_combine_caron_ttb_lt.png b/Tests/images/test_combine_caron_ttb_lt.png new file mode 100644 index 000000000..1ac181afb Binary files /dev/null and b/Tests/images/test_combine_caron_ttb_lt.png differ diff --git a/Tests/images/test_combine_double_breve_below.png b/Tests/images/test_combine_double_breve_below.png new file mode 100644 index 000000000..1b0e9a17c Binary files /dev/null and b/Tests/images/test_combine_double_breve_below.png differ diff --git a/Tests/images/test_combine_double_breve_below_ma.png b/Tests/images/test_combine_double_breve_below_ma.png new file mode 100644 index 000000000..78f3f0a84 Binary files /dev/null and b/Tests/images/test_combine_double_breve_below_ma.png differ diff --git a/Tests/images/test_combine_double_breve_below_ra.png b/Tests/images/test_combine_double_breve_below_ra.png new file mode 100644 index 000000000..43b8fc31c Binary files /dev/null and b/Tests/images/test_combine_double_breve_below_ra.png differ diff --git a/Tests/images/test_combine_double_breve_below_ttb.png b/Tests/images/test_combine_double_breve_below_ttb.png new file mode 100644 index 000000000..62f809067 Binary files /dev/null and b/Tests/images/test_combine_double_breve_below_ttb.png differ diff --git a/Tests/images/test_combine_double_breve_below_ttb_mt.png b/Tests/images/test_combine_double_breve_below_ttb_mt.png new file mode 100644 index 000000000..8a04229a9 Binary files /dev/null and b/Tests/images/test_combine_double_breve_below_ttb_mt.png differ diff --git a/Tests/images/test_combine_double_breve_below_ttb_rt.png b/Tests/images/test_combine_double_breve_below_ttb_rt.png new file mode 100644 index 000000000..dfb92e4a4 Binary files /dev/null and b/Tests/images/test_combine_double_breve_below_ttb_rt.png differ diff --git a/Tests/images/test_combine_double_breve_below_ttb_st.png b/Tests/images/test_combine_double_breve_below_ttb_st.png new file mode 100644 index 000000000..6af90970b Binary files /dev/null and b/Tests/images/test_combine_double_breve_below_ttb_st.png differ diff --git a/Tests/images/test_combine_overline.png b/Tests/images/test_combine_overline.png new file mode 100644 index 000000000..8d164ebc2 Binary files /dev/null and b/Tests/images/test_combine_overline.png differ diff --git a/Tests/images/test_combine_overline_la.png b/Tests/images/test_combine_overline_la.png new file mode 100644 index 000000000..8d164ebc2 Binary files /dev/null and b/Tests/images/test_combine_overline_la.png differ diff --git a/Tests/images/test_combine_overline_ra.png b/Tests/images/test_combine_overline_ra.png new file mode 100644 index 000000000..26612ea0a Binary files /dev/null and b/Tests/images/test_combine_overline_ra.png differ diff --git a/Tests/images/test_combine_overline_ttb.png b/Tests/images/test_combine_overline_ttb.png new file mode 100644 index 000000000..8cad66bac Binary files /dev/null and b/Tests/images/test_combine_overline_ttb.png differ diff --git a/Tests/images/test_combine_overline_ttb_mt.png b/Tests/images/test_combine_overline_ttb_mt.png new file mode 100644 index 000000000..69e0b82de Binary files /dev/null and b/Tests/images/test_combine_overline_ttb_mt.png differ diff --git a/Tests/images/test_combine_overline_ttb_rt.png b/Tests/images/test_combine_overline_ttb_rt.png new file mode 100644 index 000000000..994ce0242 Binary files /dev/null and b/Tests/images/test_combine_overline_ttb_rt.png differ diff --git a/Tests/images/test_combine_overline_ttb_st.png b/Tests/images/test_combine_overline_ttb_st.png new file mode 100644 index 000000000..69e0b82de Binary files /dev/null and b/Tests/images/test_combine_overline_ttb_st.png differ diff --git a/Tests/images/test_complex_unicode_text.png b/Tests/images/test_complex_unicode_text.png index f1a6f7ec6..3501b2a34 100644 Binary files a/Tests/images/test_complex_unicode_text.png and b/Tests/images/test_complex_unicode_text.png differ diff --git a/Tests/images/test_complex_unicode_text2.png b/Tests/images/test_complex_unicode_text2.png index 543b174c0..c295321db 100644 Binary files a/Tests/images/test_complex_unicode_text2.png and b/Tests/images/test_complex_unicode_text2.png differ diff --git a/Tests/images/test_direction_ltr.png b/Tests/images/test_direction_ltr.png index 42239334d..1cbc1bad9 100644 Binary files a/Tests/images/test_direction_ltr.png and b/Tests/images/test_direction_ltr.png differ diff --git a/Tests/images/test_direction_rtl.png b/Tests/images/test_direction_rtl.png index 966b67d6b..7ab6bdc19 100644 Binary files a/Tests/images/test_direction_rtl.png and b/Tests/images/test_direction_rtl.png differ diff --git a/Tests/images/test_direction_ttb.png b/Tests/images/test_direction_ttb.png index 825f3213e..a112eb4c6 100644 Binary files a/Tests/images/test_direction_ttb.png and b/Tests/images/test_direction_ttb.png differ diff --git a/Tests/images/test_direction_ttb_stroke.png b/Tests/images/test_direction_ttb_stroke.png index 3fa844e9a..c3710d6eb 100644 Binary files a/Tests/images/test_direction_ttb_stroke.png and b/Tests/images/test_direction_ttb_stroke.png differ diff --git a/Tests/images/test_kerning_features.png b/Tests/images/test_kerning_features.png index ca895735c..bded50557 100644 Binary files a/Tests/images/test_kerning_features.png and b/Tests/images/test_kerning_features.png differ diff --git a/Tests/images/test_language.png b/Tests/images/test_language.png index 8daf007b0..15ef7f93a 100644 Binary files a/Tests/images/test_language.png and b/Tests/images/test_language.png differ diff --git a/Tests/images/test_ligature_features.png b/Tests/images/test_ligature_features.png index 664e9929d..9d0882124 100644 Binary files a/Tests/images/test_ligature_features.png and b/Tests/images/test_ligature_features.png differ diff --git a/Tests/images/test_text.png b/Tests/images/test_text.png index c156399cd..2841da66f 100644 Binary files a/Tests/images/test_text.png and b/Tests/images/test_text.png differ diff --git a/Tests/images/test_x_max_and_y_offset.png b/Tests/images/test_x_max_and_y_offset.png index f8bec3e95..9cb176b9f 100644 Binary files a/Tests/images/test_x_max_and_y_offset.png and b/Tests/images/test_x_max_and_y_offset.png differ diff --git a/Tests/images/test_y_offset.png b/Tests/images/test_y_offset.png index 2d57890cb..b65fe8e47 100644 Binary files a/Tests/images/test_y_offset.png and b/Tests/images/test_y_offset.png differ diff --git a/Tests/test_font_leaks.py b/Tests/test_font_leaks.py index 015210b4d..21da589ac 100644 --- a/Tests/test_font_leaks.py +++ b/Tests/test_font_leaks.py @@ -5,7 +5,7 @@ from .helper import PillowLeakTestCase, skip_unless_feature class TestTTypeFontLeak(PillowLeakTestCase): # fails at iteration 3 in master - iterations = 10 + iterations = 40 mem_limit = 4096 # k def _test_font(self, font): @@ -13,7 +13,7 @@ class TestTTypeFontLeak(PillowLeakTestCase): draw = ImageDraw.ImageDraw(im) self._test_leak( lambda: draw.text( - (0, 0), "some text " * 1024, font=font, fill="black" # ~10k + (0, 0), "some text " * 256, font=font, fill="black" # ~10k ) ) @@ -25,7 +25,7 @@ class TestTTypeFontLeak(PillowLeakTestCase): class TestDefaultFontLeak(TestTTypeFontLeak): # fails at iteration 37 in master - iterations = 100 + iterations = 400 mem_limit = 1024 # k def test_leak(self): diff --git a/Tests/test_imagedraw.py b/Tests/test_imagedraw.py index 74b0b8ff3..08fb589fc 100644 --- a/Tests/test_imagedraw.py +++ b/Tests/test_imagedraw.py @@ -1015,7 +1015,7 @@ def test_stroke(): font = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 120) # Act - draw.text((10, 10), "A", "#f00", font, stroke_width=2, stroke_fill=stroke_fill) + draw.text((12, 12), "A", "#f00", font, stroke_width=2, stroke_fill=stroke_fill) # Assert assert_image_similar( @@ -1031,11 +1031,11 @@ def test_stroke_descender(): font = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 120) # Act - draw.text((10, 0), "y", "#f00", font, stroke_width=2, stroke_fill="#0f0") + draw.text((12, 2), "y", "#f00", font, stroke_width=2, stroke_fill="#0f0") # Assert assert_image_similar( - im, Image.open("Tests/images/imagedraw_stroke_descender.png"), 6.76 + im, Image.open("Tests/images/imagedraw_stroke_descender.png"), 6.78 ) @@ -1048,7 +1048,7 @@ def test_stroke_multiline(): # Act draw.multiline_text( - (10, 10), "A\nB", "#f00", font, stroke_width=2, stroke_fill="#0f0" + (12, 12), "A\nB", "#f00", font, stroke_width=2, stroke_fill="#0f0" ) # Assert diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index df03ac6b7..37587a0da 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -34,7 +34,7 @@ class TestImageFont: # Freetype has different metrics depending on the version. # (and, other things, but first things first) METRICS = { - (">=2.3", "<2.4"): {"multiline": 30, "textsize": 12, "getters": (13, 16)}, + (">=2.3", "<2.4"): {"multiline": 30, "textsize": 12, "getters": (12, 16)}, (">=2.7",): {"multiline": 6.2, "textsize": 2.5, "getters": (12, 16)}, "Default": {"multiline": 0.5, "textsize": 0.5, "getters": (12, 16)}, } @@ -342,7 +342,7 @@ class TestImageFont: mask = transposed_font.getmask(text) # Assert - assert mask.size == (13, 108) + assert mask.size in ((13, 107), (13, 108)) def test_unrotated_transposed_font_get_mask(self): # Arrange @@ -355,7 +355,7 @@ class TestImageFont: mask = transposed_font.getmask(text) # Assert - assert mask.size == (108, 13) + assert mask.size in ((107, 13), (108, 13)) def test_free_type_font_get_name(self): # Arrange @@ -399,7 +399,7 @@ class TestImageFont: mask = font.getmask(text) # Assert - assert mask.size == (108, 13) + assert mask.size in ((107, 13), (108, 13)) def test_load_path_not_found(self): # Arrange @@ -470,7 +470,8 @@ class TestImageFont: d = ImageDraw.Draw(img) d.text((10, 10), text, font=ttf) - assert_image_similar_tofile(img, target, self.metrics["multiline"]) + # fails with 14.7 + assert_image_similar_tofile(img, target, 6.2) def _test_fake_loading_font(self, monkeypatch, path_to_fake, fontname): # Make a copy of FreeTypeFont so we can patch the original @@ -702,10 +703,10 @@ class TestImageFont: font.set_variation_by_name("Bold") font = ImageFont.truetype("Tests/fonts/AdobeVFPrototype.ttf", 36) - self._check_text(font, "Tests/images/variation_adobe.png", 11) + self._check_text(font, "Tests/images/variation_adobe.png", 11.2) for name in ["Bold", b"Bold"]: font.set_variation_by_name(name) - self._check_text(font, "Tests/images/variation_adobe_name.png", 11) + self._check_text(font, "Tests/images/variation_adobe_name.png", 11.3) font = ImageFont.truetype("Tests/fonts/TINY5x3GX.ttf", 36) self._check_text(font, "Tests/images/variation_tiny.png", 40) @@ -727,12 +728,42 @@ class TestImageFont: font = ImageFont.truetype("Tests/fonts/AdobeVFPrototype.ttf", 36) font.set_variation_by_axes([500, 50]) - self._check_text(font, "Tests/images/variation_adobe_axes.png", 5.1) + self._check_text(font, "Tests/images/variation_adobe_axes.png", 5.8) font = ImageFont.truetype("Tests/fonts/TINY5x3GX.ttf", 36) font.set_variation_by_axes([100]) self._check_text(font, "Tests/images/variation_tiny_axes.png", 32.5) + @pytest.mark.parametrize( + "name,text,anchor", + ( + # test horizontal anchors + ("quick", "Quick", "ls"), + ("quick", "Quick", "ms"), + ("quick", "Quick", "rs"), + # test vertical anchors + ("quick", "Quick", "ma"), + ("quick", "Quick", "mt"), + ("quick", "Quick", "mm"), + ("quick", "Quick", "mb"), + ("quick", "Quick", "md"), + ), + ) + def test_anchor(self, name, text, anchor): + path = "Tests/images/test_anchor_%s_%s.png" % (name, anchor) + f = ImageFont.truetype( + "Tests/fonts/NotoSans-Regular.ttf", 48, layout_engine=self.LAYOUT_ENGINE + ) + + im = Image.new("RGB", (200, 200), "white") + d = ImageDraw.Draw(im) + d.line(((0, 100), (200, 100)), "gray") + d.line(((100, 0), (100, 200)), "gray") + d.text((100, 100), text, fill="black", anchor=anchor, font=f) + + with Image.open(path) as expected: + assert_image_similar(im, expected, 7) + @skip_unless_feature("raqm") class TestImageFont_RaqmLayout(TestImageFont): diff --git a/Tests/test_imagefontctl.py b/Tests/test_imagefontctl.py index 386dd3be6..0abd681fe 100644 --- a/Tests/test_imagefontctl.py +++ b/Tests/test_imagefontctl.py @@ -1,3 +1,5 @@ +import distutils.version + import pytest from PIL import Image, ImageDraw, ImageFont @@ -205,3 +207,92 @@ def test_language(): target = "Tests/images/test_language.png" with Image.open(target) as target_img: assert_image_similar(im, target_img, 0.5) + + +@pytest.mark.parametrize("anchor", ("lt", "mm", "rb", "sm")) +def test_anchor_ttb(anchor): + if distutils.version.StrictVersion(ImageFont.core.freetype2_version) < "2.5.1": + # FreeType 2.5.1 README: Miscellaneous Changes: + # Improved computation of emulated vertical metrics for TrueType fonts. + pytest.skip("FreeType <2.5.1 has incompatible ttb metrics") + + text = "f" + path = "Tests/images/test_anchor_ttb_%s_%s.png" % (text, anchor) + f = ImageFont.truetype("Tests/fonts/NotoSans-Regular.ttf", 120) + + im = Image.new("RGB", (200, 400), "white") + d = ImageDraw.Draw(im) + d.line(((0, 200), (200, 200)), "gray") + d.line(((100, 0), (100, 400)), "gray") + try: + d.text((100, 200), text, fill="black", anchor=anchor, direction="ttb", font=f) + except ValueError as ex: + if str(ex) == "libraqm 0.7 or greater required for 'ttb' direction": + pytest.skip("libraqm 0.7 or greater not available") + + with Image.open(path) as expected: + assert_image_similar(im, expected, 1) # fails at 5 + + +combine_tests = ( + # extends above (e.g. issue #4553) + ("caron", "a\u030C\u030C\u030C\u030C\u030Cb", None, None, 0.08), + ("caron_la", "a\u030C\u030C\u030C\u030C\u030Cb", "la", None, 0.08), + ("caron_lt", "a\u030C\u030C\u030C\u030C\u030Cb", "lt", None, 0.08), + ("caron_ls", "a\u030C\u030C\u030C\u030C\u030Cb", "ls", None, 0.08), + ("caron_ttb", "ca" + ("\u030C" * 15) + "b", None, "ttb", 0.3), + ("caron_ttb_lt", "ca" + ("\u030C" * 15) + "b", "lt", "ttb", 0.3), + # extends below + ("caron_below", "a\u032C\u032C\u032C\u032C\u032Cb", None, None, 0.02), + ("caron_below_ld", "a\u032C\u032C\u032C\u032C\u032Cb", "ld", None, 0.02), + ("caron_below_lb", "a\u032C\u032C\u032C\u032C\u032Cb", "lb", None, 0.02), + ("caron_below_ls", "a\u032C\u032C\u032C\u032C\u032Cb", "ls", None, 0.02), + ("caron_below_ttb", "a" + ("\u032C" * 15) + "b", None, "ttb", 0.03), + ("caron_below_ttb_lb", "a" + ("\u032C" * 15) + "b", "lb", "ttb", 0.03), + # extends to the right (e.g. issue #3745) + ("double_breve_below", "a\u035Ci", None, None, 0.02), + ("double_breve_below_ma", "a\u035Ci", "ma", None, 0.02), + ("double_breve_below_ra", "a\u035Ci", "ra", None, 0.02), + ("double_breve_below_ttb", "a\u035Cb", None, "ttb", 0.02), + ("double_breve_below_ttb_rt", "a\u035Cb", "rt", "ttb", 0.02), + ("double_breve_below_ttb_mt", "a\u035Cb", "mt", "ttb", 0.02), + ("double_breve_below_ttb_st", "a\u035Cb", "st", "ttb", 0.02), + # extends to the left (fail=0.064) + ("overline", "i\u0305", None, None, 0.02), + ("overline_la", "i\u0305", "la", None, 0.02), + ("overline_ra", "i\u0305", "ra", None, 0.02), + ("overline_ttb", "i\u0305", None, "ttb", 0.02), + ("overline_ttb_rt", "i\u0305", "rt", "ttb", 0.02), + ("overline_ttb_mt", "i\u0305", "mt", "ttb", 0.02), + ("overline_ttb_st", "i\u0305", "st", "ttb", 0.02), +) + + +# this tests various combining characters for anchor alignment and clipping +@pytest.mark.parametrize( + "name,text,anchor,dir,epsilon", combine_tests, ids=[r[0] for r in combine_tests] +) +def test_combine(name, text, dir, anchor, epsilon): + if ( + distutils.version.StrictVersion(ImageFont.core.freetype2_version) < "2.5.1" + and dir == "ttb" + ): + # FreeType 2.5.1 README: Miscellaneous Changes: + # Improved computation of emulated vertical metrics for TrueType fonts. + pytest.skip("FreeType <2.5.1 has incompatible ttb metrics") + + path = "Tests/images/test_combine_%s.png" % name + f = ImageFont.truetype("Tests/fonts/NotoSans-Regular.ttf", 48) + + im = Image.new("RGB", (400, 400), "white") + d = ImageDraw.Draw(im) + d.line(((0, 200), (400, 200)), "gray") + d.line(((200, 0), (200, 400)), "gray") + try: + d.text((200, 200), text, fill="black", anchor=anchor, direction=dir, font=f) + except ValueError as ex: + if str(ex) == "libraqm 0.7 or greater required for 'ttb' direction": + pytest.skip("libraqm 0.7 or greater not available") + + with Image.open(path) as expected: + assert_image_similar(im, expected, epsilon) diff --git a/src/PIL/ImageDraw.py b/src/PIL/ImageDraw.py index d0695fd84..07b3a640d 100644 --- a/src/PIL/ImageDraw.py +++ b/src/PIL/ImageDraw.py @@ -398,9 +398,9 @@ class ImageDraw: max_width = max(max_width, line_width) top = xy[1] - if anchor[1] == 'm': + if anchor[1] == "m": top -= (len(lines) - 1) * line_spacing / 2.0 - elif anchor[1] == 'd': + elif anchor[1] == "d": top -= (len(lines) - 1) * line_spacing for idx, line in enumerate(lines): @@ -408,9 +408,9 @@ class ImageDraw: width_difference = max_width - widths[idx] # first align left by anchor - if anchor[0] == 'm': + if anchor[0] == "m": left -= width_difference / 2.0 - elif anchor[0] == 'r': + elif anchor[0] == "r": left -= width_difference # then align by align parameter