From a17ed35e490a99a7dfab9833f6f3be86f004f699 Mon Sep 17 00:00:00 2001
From: Benjamin Drung <benjamin.drung@canonical.com>
Date: Fri, 15 Dec 2023 15:32:16 +0100
Subject: [PATCH] tests: Use better than nothing font
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Pillow 10.1.0 uses a version of Aileron Regular instead of the previous
“better than nothing” default font (in case FreeType support is
available). This font change changes the resulting bitmap.

Use the "better than nothing" font to keep the expected result
identical. The proper solution is either to use one specific font in
svg.path or make pillow support loading the “better than nothing”
default font.

Bug-Debian: https://bugs.debian.org/1055159
---
 tests/font.py                   | 145 ++++++++++++++++++++++++++++++++
 tests/test_boundingbox_image.py |  18 ++--
 tests/test_image.py             |  18 +++-
 3 files changed, 170 insertions(+), 11 deletions(-)
 create mode 100644 tests/font.py

diff --git a/tests/font.py b/tests/font.py
new file mode 100644
index 0000000..d375f49
--- /dev/null
+++ b/tests/font.py
@@ -0,0 +1,145 @@
+# Code taken from https://github.com/python-pillow/Pillow/blob/main/src/PIL/ImageFont.py
+#
+# License: the open source HPND License
+# Copyright (c) 1997-2003 by Secret Labs AB
+# Copyright (c) 1996-2003 by Fredrik Lundh
+
+from PIL import Image, ImageFont
+from io import BytesIO
+import base64
+
+
+def get_better_than_nothing_font():
+    font = ImageFont.ImageFont()
+    font._load_pilfont_data(
+        # courB08
+        BytesIO(
+            base64.b64decode(
+                b"""
[encoded data, 7020 characters]
++QAGAAIAzgAKANUAEw==
+"""
+            )
+        ),
+        Image.open(
+            BytesIO(
+                base64.b64decode(
+                    b"""
+iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u
+Mc4b7vuds/xzjz5/3/7u/n9vMe7vnfH/9++vPn/xyf5zhxzjt8GHw8+2d83u8x27199/nxuQ6Od9
+M43/5z2I+9n9ZtmDBwMQECDRQw/eQIQohJXxpBCNVE6QCCAAAAD//wBlAJr/AgALyj1t/wINwq0g
+LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F
+IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA
+Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791
+NAADfcoIDyP44K/jv4Y63/Z+t98Ovt+ub4T48LAAAAD//wBlAJr/AuplMlADJAAAAGuAphWpqhMx
+in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9
+SjdavWA8ePHeBIKB//81/83ndznOaXx379wAAAD//wBlAJr/AqDxW+D3AABAAbUh/QMnbQag/gAY
+AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt
+y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG
+ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY
+lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H
+/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3
+AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47
+c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/
+/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw
+pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv
+oJodAAAAAP//Yqo/83+dxePWlxl3npsel9lvLfPcqlE9725C+acfVLMEAAAA//9i+s9gwCoaaGMR
+evta/58PTEWzr21hufPjA8N+qlnBwAAAAAD//2JiWLci5v1+HmFXDqcnULE/MxgYGBj+f6CaJQAA
+AAD//2Ji2FrkY3iYpYC5qDeGgeEMAwPDvwQBBoYvcTwOVLMEAAAA//9isDBgkP///0EOg9z35v//
+Gc/eeW7BwPj5+QGZhANUswMAAAD//2JgqGBgYGBgqEMXlvhMPUsAAAAA//8iYDd1AAAAAP//AwDR
+w7IkEbzhVQAAAABJRU5ErkJggg==
+"""
+                )
+            )
+        ),
+    )
+    return font
diff --git a/tests/test_boundingbox_image.py b/tests/test_boundingbox_image.py
index 21f19a7..414f0b1 100644
--- a/tests/test_boundingbox_image.py
+++ b/tests/test_boundingbox_image.py
@@ -5,6 +5,7 @@
 
 from PIL import Image, ImageDraw, ImageColor, ImageChops
 from svg.path.path import CubicBezier, QuadraticBezier, Line, Arc
+from .font import get_better_than_nothing_font
 
 
 RED = ImageColor.getcolor("red", mode="RGB")
@@ -57,17 +58,15 @@ def draw_boundingbox(self, path):
         sys.platform != "linux", reason="Different platforms have different fonts"
     )
     def test_image(self):
-        self.draw.text((10, 10), "This is an SVG line:")
-        self.draw.text(
-            (10, 100),
-            "The red line is a bounding box.",
-        )
+        font = get_better_than_nothing_font()
+        self.draw.text((10, 10), "This is an SVG line:", font=font)
+        self.draw.text((10, 100), "The red line is a bounding box.", font=font)
 
         line1 = Line(40 + 60j, 200 + 80j)
         self.draw_path(line1)
         self.draw_boundingbox(line1)
 
-        self.draw.text((10, 140), "These are Arc segments:")
+        self.draw.text((10, 140), "These are Arc segments:", font=font)
         arc1 = Arc(260 + 320j, 100 + 100j, 0, 1, 1, 260 + 319j)
         self.draw_path(arc1)
         self.draw_boundingbox(arc1)
@@ -83,6 +82,7 @@ def test_image(self):
         self.draw.text(
             (10, 500),
             "Next we have a quadratic bezier curve, with one tangent:",
+            font=font,
         )
         start = 30 + 600j
         control = 400 + 540j
@@ -95,12 +95,16 @@ def test_image(self):
         self.draw.text(
             (10, 670),
             "The white dot is the control point, and the cyan lines are ",
+            font=font,
+        )
+        self.draw.text(
+            (10, 690), "illustrating the how the control point works.", font=font
         )
-        self.draw.text((10, 690), "illustrating the how the control point works.")
 
         self.draw.text(
             (10, 730),
             "Lastly is a cubic bezier, with 2 tangents, and 2 control points:",
+            font=font,
         )
 
         start = 200 + 800j
diff --git a/tests/test_image.py b/tests/test_image.py
index 49967ea..ae3a357 100644
--- a/tests/test_image.py
+++ b/tests/test_image.py
@@ -4,6 +4,7 @@
 from math import sqrt
 
 from svg.path.path import CubicBezier, QuadraticBezier, Line, Arc
+from .font import get_better_than_nothing_font
 
 
 RED = ImageColor.getcolor("red", mode="RGB")
@@ -57,25 +58,30 @@ def draw_tangents(self, path, count):
             self.draw.line([c2t(p), c2t(tt + p)], fill=YELLOW, width=1)
 
     def test_image(self):
-        self.draw.text((10, 10), "This is an SVG line:")
+        font = get_better_than_nothing_font()
+        self.draw.text((10, 10), "This is an SVG line:", font=font)
         self.draw.text(
             (10, 100),
             "The red line is a tangent, and the yellow is 90 degrees from that.",
+            font=font,
         )
 
         line1 = Line(40 + 60j, 200 + 80j)
         self.draw_path(line1)
         self.draw_tangents(line1, 1)
 
-        self.draw.text((10, 140), "This is an Arc segment, almost a whole circle:")
+        self.draw.text(
+            (10, 140), "This is an Arc segment, almost a whole circle:", font=font
+        )
         arc1 = Arc(260 + 320j, 100 + 100j, 0, 1, 1, 260 + 319j)
         self.draw_path(arc1)
         self.draw_tangents(arc1, 5)
-        self.draw.text((10, 460), "With five tangents.")
+        self.draw.text((10, 460), "With five tangents.", font=font)
 
         self.draw.text(
             (10, 500),
             "Next we have a quadratic bezier curve, with one tangent:",
+            font=font,
         )
         start = 30 + 600j
         control = 400 + 540j
@@ -88,12 +94,16 @@ def test_image(self):
         self.draw.text(
             (10, 670),
             "The white dot is the control point, and the cyan lines are ",
+            font=font,
+        )
+        self.draw.text(
+            (10, 690), "illustrating the how the control point works.", font=font
         )
-        self.draw.text((10, 690), "illustrating the how the control point works.")
 
         self.draw.text(
             (10, 730),
             "Lastly is a cubic bezier, with 2 tangents, and 2 control points:",
+            font=font,
         )
 
         start = 30 + 800j
