Repository: python-pillow/Pillow

Issue:
TestImageFont.test_multiline_spacing broken with Freetype 2.9
With the release of Freetype 2.9, we (openSUSE) see a test failure with Pillow 5.0:

<pre>
=================================== FAILURES ===================================
_____________________ TestImageFont.test_multiline_spacing _____________________

self = <test_imagefont.TestImageFont testMethod=test_multiline_spacing>

    def test_multiline_spacing(self):
        ttf = self.get_font()

        im = Image.new(mode='RGB', size=(300, 100))
        draw = ImageDraw.Draw(im)
        draw.multiline_text((0, 0), TEST_TEXT, font=ttf, spacing=10)

        target = 'Tests/images/multiline_text_spacing.png'
        target_img = Image.open(target)

        # Epsilon ~.5 fails with FreeType 2.7
>       self.assert_image_similar(im, target_img, self.metrics['multiline'])

Tests/test_imagefont.py:257:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <test_imagefont.TestImageFont testMethod=test_multiline_spacing>
a = <PIL.Image.Image image mode=RGB size=300x100 at 0x7F68003135D0>
b = <PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x100 at 0x7F6800313610>
epsilon = 0.5, msg = None

    def assert_image_similar(self, a, b, epsilon, msg=None):
        epsilon = float(epsilon)
        self.assertEqual(
            a.mode, b.mode,
            msg or "got mode %r, expected %r" % (a.mode, b.mode))
        self.assertEqual(
            a.size, b.size,
            msg or "got size %r, expected %r" % (a.size, b.size))

        a, b = convert_to_comparable(a, b)

        diff = 0
        for ach, bch in zip(a.split(), b.split()):
            chdiff = ImageMath.eval("abs(a - b)", a=ach, b=bch).convert('L')
            diff += sum(i * num for i, num in enumerate(chdiff.histogram()))

        ave_diff = float(diff)/(a.size[0]*a.size[1])
        try:
            self.assertGreaterEqual(
                epsilon, ave_diff,
                (msg or '') +
                " average pixel value difference %.4f > epsilon %.4f" % (
                    ave_diff, epsilon))
        except Exception as e:
            if HAS_UPLOADER:
                try:
                    url = test_image_results.upload(a, b)
                    logger.error("Url for test images: %s" % url)
                except:
                    pass
>           raise e
E           AssertionError:  average pixel value difference 6.1854 > epsilon 0.5000

Tests/helper.py:153: AssertionError
------------------------------ Captured log call -------------------------------
PngImagePlugin.py          137 DEBUG    STREAM 'IHDR' 16 13
PngImagePlugin.py          137 DEBUG    STREAM 'IDAT' 41 2783
============== 1 failed, 831 passed, 53 skipped in 13.26 seconds ===============
</pre>


Discussion:
Could you add a section in this for freetype 2.9 and let us know if there are any differences required from the 2.8 version? (this is in test_imagefont.py)  

```
    # Freetype has different metrics depending on the version.
    # (and, other things, but first things first)
    METRICS = {
                ('2', '3'): {'multiline': 30,
                             'textsize': 12,
                             'getters': (13, 16)},
                ('2', '7'): {'multiline': 6.2,
                             'textsize': 2.5,
                             'getters': (12, 16)},
                ('2', '8'): {'multiline': 6.2,
                             'textsize': 2.5,
                             'getters': (12, 16)},
                'Default': {'multiline': 0.5,
                            'textsize': 0.5,
                            'getters': (12, 16)},
                }
```
Just copying the 2.8 values to a new 2.9 entry fixed the tests, thanks a lot!

Resolving patch:
diff --git a/winbuild/config.py b/winbuild/config.py
--- a/winbuild/config.py
+++ b/winbuild/config.py
@@ -34,9 +34,9 @@
         'dir': 'tiff-4.0.9',
     },
     'freetype': {
-        'url': 'https://download.savannah.gnu.org/releases/freetype/freetype-2.8.1.tar.gz',
-        'filename': PILLOW_DEPENDS_DIR + 'freetype-2.8.1.tar.gz',
-        'dir': 'freetype-2.8.1',
+        'url': 'https://download.savannah.gnu.org/releases/freetype/freetype-2.9.tar.gz',
+        'filename': PILLOW_DEPENDS_DIR + 'freetype-2.9.tar.gz',
+        'dir': 'freetype-2.9',
     },
     'lcms': {
         'url': SF_MIRROR+'/project/lcms/lcms/2.7/lcms2-2.7.zip',


Test patch:
diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py
--- a/Tests/test_imagefont.py
+++ b/Tests/test_imagefont.py
@@ -58,6 +58,9 @@ class TestImageFont(PillowTestCase):
                 ('2', '8'): {'multiline': 6.2,
                              'textsize': 2.5,
                              'getters': (12, 16)},
+                ('2', '9'): {'multiline': 6.2,
+                             'textsize': 2.5,
+                             'getters': (12, 16)},
                 'Default': {'multiline': 0.5,
                             'textsize': 0.5,
                             'getters': (12, 16)},
@@ -406,10 +409,10 @@ def test_render_empty(self):
         im = Image.new(mode='RGB', size=(300, 100))
         target = im.copy()
         draw = ImageDraw.Draw(im)
-        #should not crash here. 
+        #should not crash here.
         draw.text((10, 10), '', font=font)
         self.assert_image_equal(im, target)
-        
+
     def test_unicode_pilfont(self):
         # should not segfault, should return UnicodeDecodeError
         # issue #2826