diff --git a/Tests/images/imagedraw_default_font_size.png b/Tests/images/imagedraw_default_font_size.png new file mode 100644 index 000000000..f695b5cd6 Binary files /dev/null and b/Tests/images/imagedraw_default_font_size.png differ diff --git a/Tests/test_imagedraw.py b/Tests/test_imagedraw.py index f4e9b36e2..e59ad5d43 100644 --- a/Tests/test_imagedraw.py +++ b/Tests/test_imagedraw.py @@ -1,8 +1,9 @@ +import contextlib import os.path import pytest -from PIL import Image, ImageColor, ImageDraw, ImageFont +from PIL import Image, ImageColor, ImageDraw, ImageFont, features from .helper import ( assert_image_equal, @@ -1344,6 +1345,32 @@ def test_setting_default_font(): assert isinstance(draw.getfont(), ImageFont.load_default().__class__) +def test_default_font_size(): + freetype_support = features.check_module("freetype2") + text = "Default font at a specific size." + + im = Image.new("RGB", (220, 25)) + draw = ImageDraw.Draw(im) + with contextlib.nullcontext() if freetype_support else pytest.raises(ImportError): + draw.text((0, 0), text, font_size=16) + assert_image_equal_tofile(im, "Tests/images/imagedraw_default_font_size.png") + + with contextlib.nullcontext() if freetype_support else pytest.raises(ImportError): + assert draw.textlength(text, font_size=16) == 216 + + with contextlib.nullcontext() if freetype_support else pytest.raises(ImportError): + assert draw.textbbox((0, 0), text, font_size=16) == (0, 3, 216, 19) + + im = Image.new("RGB", (220, 25)) + draw = ImageDraw.Draw(im) + with contextlib.nullcontext() if freetype_support else pytest.raises(ImportError): + draw.multiline_text((0, 0), text, font_size=16) + assert_image_equal_tofile(im, "Tests/images/imagedraw_default_font_size.png") + + with contextlib.nullcontext() if freetype_support else pytest.raises(ImportError): + assert draw.multiline_textbbox((0, 0), text, font_size=16) == (0, 3, 216, 19) + + @pytest.mark.parametrize("bbox", BBOX) def test_same_color_outline(bbox): # Prepare shape diff --git a/src/PIL/ImageDraw.py b/src/PIL/ImageDraw.py index 7d1790faa..fbf320d72 100644 --- a/src/PIL/ImageDraw.py +++ b/src/PIL/ImageDraw.py @@ -113,6 +113,15 @@ class ImageDraw: self.font = ImageFont.load_default() return self.font + def _getfont(self, font_size): + if font_size is not None: + from . import ImageFont + + font = ImageFont.load_default(font_size) + else: + font = self.getfont() + return font + def _getink(self, ink, fill=None): if ink is None and fill is None: if self.fill: @@ -456,6 +465,13 @@ class ImageDraw: **kwargs, ): """Draw text.""" + if embedded_color and self.mode not in ("RGB", "RGBA"): + msg = "Embedded color supported only in RGB and RGBA modes" + raise ValueError(msg) + + if font is None: + font = self._getfont(kwargs.get("font_size")) + if self._multiline_check(text): return self.multiline_text( xy, @@ -473,13 +489,6 @@ class ImageDraw: embedded_color, ) - if embedded_color and self.mode not in ("RGB", "RGBA"): - msg = "Embedded color supported only in RGB and RGBA modes" - raise ValueError(msg) - - if font is None: - font = self.getfont() - def getink(fill): ink, fill = self._getink(fill) if ink is None: @@ -570,6 +579,8 @@ class ImageDraw: stroke_width=0, stroke_fill=None, embedded_color=False, + *, + font_size=None, ): if direction == "ttb": msg = "ttb direction is unsupported for multiline text" @@ -584,6 +595,9 @@ class ImageDraw: msg = "anchor not supported for multiline text" raise ValueError(msg) + if font is None: + font = self._getfont(font_size) + widths = [] max_width = 0 lines = self._multiline_split(text) @@ -645,6 +659,8 @@ class ImageDraw: features=None, language=None, embedded_color=False, + *, + font_size=None, ): """Get the length of a given string, in pixels with 1/64 precision.""" if self._multiline_check(text): @@ -655,7 +671,7 @@ class ImageDraw: raise ValueError(msg) if font is None: - font = self.getfont() + font = self._getfont(font_size) mode = "RGBA" if embedded_color else self.fontmode return font.getlength(text, mode, direction, features, language) @@ -672,12 +688,17 @@ class ImageDraw: language=None, stroke_width=0, embedded_color=False, + *, + font_size=None, ): """Get the bounding box of a given string, in pixels.""" if embedded_color and self.mode not in ("RGB", "RGBA"): msg = "Embedded color supported only in RGB and RGBA modes" raise ValueError(msg) + if font is None: + font = self._getfont(font_size) + if self._multiline_check(text): return self.multiline_textbbox( xy, @@ -693,8 +714,6 @@ class ImageDraw: embedded_color, ) - if font is None: - font = self.getfont() mode = "RGBA" if embedded_color else self.fontmode bbox = font.getbbox( text, mode, direction, features, language, stroke_width, anchor @@ -714,6 +733,8 @@ class ImageDraw: language=None, stroke_width=0, embedded_color=False, + *, + font_size=None, ): if direction == "ttb": msg = "ttb direction is unsupported for multiline text" @@ -728,6 +749,9 @@ class ImageDraw: msg = "anchor not supported for multiline text" raise ValueError(msg) + if font is None: + font = self._getfont(font_size) + widths = [] max_width = 0 lines = self._multiline_split(text)