1
from __future__ import annotations
8
from PIL import Image, ImageDraw, ImageFont, _util, features
10
from .helper import assert_image_equal_tofile
12
fonts = [ImageFont.load_default_imagefont()]
13
if not features.check_module("freetype2"):
14
default_font = ImageFont.load_default()
15
if isinstance(default_font, ImageFont.ImageFont):
16
fonts.append(default_font)
19
@pytest.mark.parametrize("font", fonts)
20
def test_default_font(font: ImageFont.ImageFont) -> None:
22
txt = 'This is a "better than nothing" default font.'
23
im = Image.new(mode="RGB", size=(300, 100))
24
draw = ImageDraw.Draw(im)
27
draw.text((10, 10), txt, font=font)
30
assert_image_equal_tofile(im, "Tests/images/default_font.png")
33
def test_without_freetype() -> None:
34
original_core = ImageFont.core
35
if features.check_module("freetype2"):
36
ImageFont.core = _util.DeferredError(ImportError("Disabled for testing"))
38
with pytest.raises(ImportError):
39
ImageFont.truetype("Tests/fonts/FreeMono.ttf")
41
assert isinstance(ImageFont.load_default(), ImageFont.ImageFont)
43
with pytest.raises(ImportError):
44
ImageFont.load_default(size=14)
46
ImageFont.core = original_core
49
@pytest.mark.parametrize("font", fonts)
50
def test_unicode(font: ImageFont.ImageFont) -> None:
53
with pytest.raises(UnicodeEncodeError):
57
@pytest.mark.parametrize("font", fonts)
58
def test_textbbox(font: ImageFont.ImageFont) -> None:
59
im = Image.new("RGB", (200, 200))
60
d = ImageDraw.Draw(im)
61
assert d.textlength("test", font=font) == 24
62
assert d.textbbox((0, 0), "test", font=font) == (0, 0, 24, 11)
65
def test_decompression_bomb() -> None:
66
glyph = struct.pack(">hhhhhhhhhh", 1, 0, 0, 0, 256, 256, 0, 0, 256, 256)
67
fp = BytesIO(b"PILfont\n\nDATA\n" + glyph * 256)
69
font = ImageFont.ImageFont()
70
font._load_pilfont_data(fp, Image.new("L", (256, 256)))
71
with pytest.raises(Image.DecompressionBombError):
72
font.getmask("A" * 1_000_000)
75
@pytest.mark.timeout(4)
76
def test_oom() -> None:
78
">hhhhhhhhhh", 1, 0, -32767, -32767, 32767, 32767, -32767, -32767, 32767, 32767
80
fp = BytesIO(b"PILfont\n\nDATA\n" + glyph * 256)
82
font = ImageFont.ImageFont()
83
font._load_pilfont_data(fp, Image.new("L", (1, 1)))
84
font.getmask("A" * 1_000_000)