diff --git a/Tests/test_deprecate.py b/Tests/test_deprecate.py index c7a7a9ff5..f175b90af 100644 --- a/Tests/test_deprecate.py +++ b/Tests/test_deprecate.py @@ -6,11 +6,6 @@ from PIL import _deprecate @pytest.mark.parametrize( "version, expected", [ - ( - 10, - "Old thing is deprecated and will be removed in Pillow 10 " - r"\(2023-07-01\)\. Use new thing instead\.", - ), ( 11, "Old thing is deprecated and will be removed in Pillow 11 " @@ -57,18 +52,18 @@ def test_old_version(deprecated, plural, expected): def test_plural(): expected = ( - r"Old things are deprecated and will be removed in Pillow 10 \(2023-07-01\)\. " + r"Old things are deprecated and will be removed in Pillow 11 \(2024-10-15\)\. " r"Use new thing instead\." ) with pytest.warns(DeprecationWarning, match=expected): - _deprecate.deprecate("Old things", 10, "new thing", plural=True) + _deprecate.deprecate("Old things", 11, "new thing", plural=True) def test_replacement_and_action(): expected = "Use only one of 'replacement' and 'action'" with pytest.raises(ValueError, match=expected): _deprecate.deprecate( - "Old thing", 10, replacement="new thing", action="Upgrade to new thing" + "Old thing", 11, replacement="new thing", action="Upgrade to new thing" ) @@ -81,16 +76,16 @@ def test_replacement_and_action(): ) def test_action(action): expected = ( - r"Old thing is deprecated and will be removed in Pillow 10 \(2023-07-01\)\. " + r"Old thing is deprecated and will be removed in Pillow 11 \(2024-10-15\)\. " r"Upgrade to new thing\." ) with pytest.warns(DeprecationWarning, match=expected): - _deprecate.deprecate("Old thing", 10, action=action) + _deprecate.deprecate("Old thing", 11, action=action) def test_no_replacement_or_action(): expected = ( - r"Old thing is deprecated and will be removed in Pillow 10 \(2023-07-01\)" + r"Old thing is deprecated and will be removed in Pillow 11 \(2024-10-15\)" ) with pytest.warns(DeprecationWarning, match=expected): - _deprecate.deprecate("Old thing", 10) + _deprecate.deprecate("Old thing", 11) diff --git a/Tests/test_font_pcf.py b/Tests/test_font_pcf.py index c217378fb..815ef1d92 100644 --- a/Tests/test_font_pcf.py +++ b/Tests/test_font_pcf.py @@ -82,9 +82,6 @@ def test_textsize(request, tmp_path): assert dy == 20 assert dx in (0, 10) assert font.getlength(chr(i)) == dx - with pytest.warns(DeprecationWarning) as log: - assert font.getsize(chr(i)) == (dx, dy) - assert len(log) == 1 for i in range(len(message)): msg = message[: i + 1] assert font.getlength(msg) == len(msg) * 10 diff --git a/Tests/test_imagedraw.py b/Tests/test_imagedraw.py index 5295021a3..7ffd7969d 100644 --- a/Tests/test_imagedraw.py +++ b/Tests/test_imagedraw.py @@ -1224,21 +1224,6 @@ def test_textbbox_stroke(): assert draw.textbbox((2, 2), "ABC\nAaaa", font, stroke_width=4) == (-2, 2, 54, 50) -def test_textsize_deprecation(): - im = Image.new("RGB", (W, H)) - draw = ImageDraw.Draw(im) - - with pytest.warns(DeprecationWarning) as log: - draw.textsize("Hello") - assert len(log) == 1 - with pytest.warns(DeprecationWarning) as log: - draw.textsize("Hello\nWorld") - assert len(log) == 1 - with pytest.warns(DeprecationWarning) as log: - draw.multiline_textsize("Hello\nWorld") - assert len(log) == 1 - - @skip_unless_feature("freetype2") def test_stroke(): for suffix, stroke_fill in {"same": None, "different": "#0f0"}.items(): diff --git a/Tests/test_imagedraw2.py b/Tests/test_imagedraw2.py index 6fc829f1a..a8a2ee1fc 100644 --- a/Tests/test_imagedraw2.py +++ b/Tests/test_imagedraw2.py @@ -2,7 +2,7 @@ import os.path import pytest -from PIL import Image, ImageDraw, ImageDraw2 +from PIL import Image, ImageDraw, ImageDraw2, features from .helper import ( assert_image_equal, @@ -171,19 +171,18 @@ def test_text(): @skip_unless_feature("freetype2") -def test_textsize(): +def test_textbbox(): # Arrange im = Image.new("RGB", (W, H)) draw = ImageDraw2.Draw(im) font = ImageDraw2.Font("white", FONT_PATH) # Act - with pytest.warns(DeprecationWarning) as log: - size = draw.textsize("ImageDraw2", font) - assert len(log) == 1 + bbox = draw.textbbox((0, 0), "ImageDraw2", font) # Assert - assert size[1] == 12 + right = 72 if features.check_feature("raqm") else 70 + assert bbox == (0, 2, right, 12) @skip_unless_feature("freetype2") diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index ca76ca6b2..623365d53 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -251,27 +251,6 @@ def test_draw_align(font): draw.text((100, 40), line, (0, 0, 0), font=font, align="left") -def test_multiline_size(font): - im = Image.new(mode="RGB", size=(300, 100)) - draw = ImageDraw.Draw(im) - - with pytest.warns(DeprecationWarning) as log: - # Test that textsize() correctly connects to multiline_textsize() - assert draw.textsize(TEST_TEXT, font=font) == draw.multiline_textsize( - TEST_TEXT, font=font - ) - - # Test that multiline_textsize corresponds to ImageFont.textsize() - # for single line text - assert font.getsize("A") == draw.multiline_textsize("A", font=font) - - # Test that textsize() can pass on additional arguments - # to multiline_textsize() - draw.textsize(TEST_TEXT, font=font, spacing=4) - draw.textsize(TEST_TEXT, font, 4) - assert len(log) == 6 - - def test_multiline_bbox(font): im = Image.new(mode="RGB", size=(300, 100)) draw = ImageDraw.Draw(im) @@ -298,12 +277,6 @@ def test_multiline_width(font): draw.textbbox((0, 0), "longest line", font=font)[2] == draw.multiline_textbbox((0, 0), "longest line\nline", font=font)[2] ) - with pytest.warns(DeprecationWarning) as log: - assert ( - draw.textsize("longest line", font=font)[0] - == draw.multiline_textsize("longest line\nline", font=font)[0] - ) - assert len(log) == 2 def test_multiline_spacing(font): @@ -326,29 +299,23 @@ def test_rotated_transposed_font(font, orientation): # Original font draw.font = font - with pytest.warns(DeprecationWarning) as log: - box_size_a = draw.textsize(word) - assert box_size_a == font.getsize(word) - assert len(log) == 2 bbox_a = draw.textbbox((10, 10), word) # Rotated font draw.font = transposed_font - with pytest.warns(DeprecationWarning) as log: - box_size_b = draw.textsize(word) - assert box_size_b == transposed_font.getsize(word) - assert len(log) == 2 bbox_b = draw.textbbox((20, 20), word) - # Check (w,h) of box a is (h,w) of box b - assert box_size_a[0] == box_size_b[1] - assert box_size_a[1] == box_size_b[0] + # Check (w, h) of box a is (h, w) of box b + assert ( + bbox_a[2] - bbox_a[0], + bbox_a[3] - bbox_a[1], + ) == ( + bbox_b[3] - bbox_b[1], + bbox_b[2] - bbox_b[0], + ) - # Check bbox b is (20, 20, 20 + h, 20 + w) - assert bbox_b[0] == 20 - assert bbox_b[1] == 20 - assert bbox_b[2] == 20 + bbox_a[3] - bbox_a[1] - assert bbox_b[3] == 20 + bbox_a[2] - bbox_a[0] + # Check top left co-ordinates are correct + assert bbox_b[:2] == (20, 20) # text length is undefined for vertical text with pytest.raises(ValueError): @@ -373,28 +340,25 @@ def test_unrotated_transposed_font(font, orientation): # Original font draw.font = font - with pytest.warns(DeprecationWarning) as log: - box_size_a = draw.textsize(word) - assert len(log) == 1 bbox_a = draw.textbbox((10, 10), word) length_a = draw.textlength(word) # Rotated font draw.font = transposed_font - with pytest.warns(DeprecationWarning) as log: - box_size_b = draw.textsize(word) - assert len(log) == 1 bbox_b = draw.textbbox((20, 20), word) length_b = draw.textlength(word) # Check boxes a and b are same size - assert box_size_a == box_size_b + assert ( + bbox_a[2] - bbox_a[0], + bbox_a[3] - bbox_a[1], + ) == ( + bbox_b[2] - bbox_b[0], + bbox_b[3] - bbox_b[1], + ) - # Check bbox b is (20, 20, 20 + w, 20 + h) - assert bbox_b[0] == 20 - assert bbox_b[1] == 20 - assert bbox_b[2] == 20 + bbox_a[2] - bbox_a[0] - assert bbox_b[3] == 20 + bbox_a[3] - bbox_a[1] + # Check top left co-ordinates are correct + assert bbox_b[:2] == (20, 20) assert length_a == length_b @@ -447,19 +411,6 @@ def test_free_type_font_get_metrics(font): assert (ascent, descent) == (16, 4) -def test_free_type_font_get_offset(font): - # Arrange - text = "offset this" - - # Act - with pytest.warns(DeprecationWarning) as log: - offset = font.getoffset(text) - - # Assert - assert len(log) == 1 - assert offset == (0, 3) - - def test_free_type_font_get_mask(font): # Arrange text = "mask this" @@ -618,19 +569,6 @@ def test_imagefont_getters(font): assert font.getlength("M") == 12 assert font.getlength("y") == 12 assert font.getlength("a") == 12 - with pytest.warns(DeprecationWarning) as log: - assert font.getsize("A") == (12, 16) - assert font.getsize("AB") == (24, 16) - assert font.getsize("M") == (12, 16) - assert font.getsize("y") == (12, 20) - assert font.getsize("a") == (12, 16) - assert font.getsize_multiline("A") == (12, 16) - assert font.getsize_multiline("AB") == (24, 16) - assert font.getsize_multiline("a") == (12, 16) - assert font.getsize_multiline("ABC\n") == (36, 36) - assert font.getsize_multiline("ABC\nA") == (36, 36) - assert font.getsize_multiline("ABC\nAaaa") == (48, 36) - assert len(log) == 11 @pytest.mark.parametrize("stroke_width", (0, 2)) @@ -641,16 +579,6 @@ def test_getsize_stroke(font, stroke_width): 12 + stroke_width, 16 + stroke_width, ) - with pytest.warns(DeprecationWarning) as log: - assert font.getsize("A", stroke_width=stroke_width) == ( - 12 + stroke_width * 2, - 16 + stroke_width * 2, - ) - assert font.getsize_multiline("ABC\nAaaa", stroke_width=stroke_width) == ( - 48 + stroke_width * 2, - 36 + stroke_width * 4, - ) - assert len(log) == 2 def test_complex_font_settings(): @@ -781,11 +709,8 @@ def test_textbbox_non_freetypefont(): im = Image.new("RGB", (200, 200)) d = ImageDraw.Draw(im) default_font = ImageFont.load_default() - with pytest.warns(DeprecationWarning) as log: - width, height = d.textsize("test", font=default_font) - assert len(log) == 1 - assert d.textlength("test", font=default_font) == width - assert d.textbbox((0, 0), "test", font=default_font) == (0, 0, width, height) + assert d.textlength("test", font=default_font) == 24 + assert d.textbbox((0, 0), "test", font=default_font) == (0, 0, 24, 11) @pytest.mark.parametrize( diff --git a/docs/deprecations.rst b/docs/deprecations.rst index 0eb3d6b41..45b2f4200 100644 --- a/docs/deprecations.rst +++ b/docs/deprecations.rst @@ -12,57 +12,6 @@ Deprecated features Below are features which are considered deprecated. Where appropriate, a ``DeprecationWarning`` is issued. -.. _Font size and offset methods: - -Font size and offset methods -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. deprecated:: 9.2.0 - -Several functions for computing the size and offset of rendered text -have been deprecated and will be removed in Pillow 10 (2023-07-01): - -=========================================================================== ============================================================================================================= -Deprecated Use instead -=========================================================================== ============================================================================================================= -:py:meth:`.FreeTypeFont.getsize` and :py:meth:`.FreeTypeFont.getoffset` :py:meth:`.FreeTypeFont.getbbox` and :py:meth:`.FreeTypeFont.getlength` -:py:meth:`.FreeTypeFont.getsize_multiline` :py:meth:`.ImageDraw.multiline_textbbox` -:py:meth:`.ImageFont.getsize` :py:meth:`.ImageFont.getbbox` and :py:meth:`.ImageFont.getlength` -:py:meth:`.TransposedFont.getsize` :py:meth:`.TransposedFont.getbbox` and :py:meth:`.TransposedFont.getlength` -:py:meth:`.ImageDraw.textsize` and :py:meth:`.ImageDraw.multiline_textsize` :py:meth:`.ImageDraw.textbbox`, :py:meth:`.ImageDraw.textlength` and :py:meth:`.ImageDraw.multiline_textbbox` -:py:meth:`.ImageDraw2.Draw.textsize` :py:meth:`.ImageDraw2.Draw.textbbox` and :py:meth:`.ImageDraw2.Draw.textlength` -=========================================================================== ============================================================================================================= - -Previous code:: - - from PIL import Image, ImageDraw, ImageFont - - font = ImageFont.truetype("Tests/fonts/FreeMono.ttf") - width, height = font.getsize("Hello world") - left, top = font.getoffset("Hello world") - - im = Image.new("RGB", (100, 100)) - draw = ImageDraw.Draw(im) - width, height = draw.textsize("Hello world") - - width, height = font.getsize_multiline("Hello\nworld") - width, height = draw.multiline_textsize("Hello\nworld") - -Use instead:: - - from PIL import Image, ImageDraw, ImageFont - - font = ImageFont.truetype("Tests/fonts/FreeMono.ttf") - left, top, right, bottom = font.getbbox("Hello world") - width, height = right - left, bottom - top - - im = Image.new("RGB", (100, 100)) - draw = ImageDraw.Draw(im) - width = draw.textlength("Hello world") - - left, top, right, bottom = draw.multiline_textbbox((0, 0), "Hello\nworld") - width, height = right - left, bottom - top - PSFile ~~~~~~ @@ -184,6 +133,55 @@ FitsStubImagePlugin The stub image plugin ``FitsStubImagePlugin`` has been removed. FITS images can be read without a handler through :mod:`~PIL.FitsImagePlugin` instead. +Font size and offset methods +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. deprecated:: 9.2.0 +.. versionremoved:: 10.0.0 + +Several functions for computing the size and offset of rendered text have been removed: + +=============================================================== ============================================================================================================= +Removed Use instead +=============================================================== ============================================================================================================= +``FreeTypeFont.getsize()`` and ``FreeTypeFont.getoffset()`` :py:meth:`.FreeTypeFont.getbbox` and :py:meth:`.FreeTypeFont.getlength` +``FreeTypeFont.getsize_multiline()`` :py:meth:`.ImageDraw.multiline_textbbox` +``ImageFont.getsize()`` :py:meth:`.ImageFont.getbbox` and :py:meth:`.ImageFont.getlength` +``TransposedFont.getsize()`` :py:meth:`.TransposedFont.getbbox` and :py:meth:`.TransposedFont.getlength` +``ImageDraw.textsize()`` and ``ImageDraw.multiline_textsize()`` :py:meth:`.ImageDraw.textbbox`, :py:meth:`.ImageDraw.textlength` and :py:meth:`.ImageDraw.multiline_textbbox` +``ImageDraw2.Draw.textsize()`` :py:meth:`.ImageDraw2.Draw.textbbox` and :py:meth:`.ImageDraw2.Draw.textlength` +=============================================================== ============================================================================================================= + +Previous code:: + + from PIL import Image, ImageDraw, ImageFont + + font = ImageFont.truetype("Tests/fonts/FreeMono.ttf") + width, height = font.getsize("Hello world") + left, top = font.getoffset("Hello world") + + im = Image.new("RGB", (100, 100)) + draw = ImageDraw.Draw(im) + width, height = draw.textsize("Hello world") + + width, height = font.getsize_multiline("Hello\nworld") + width, height = draw.multiline_textsize("Hello\nworld") + +Use instead:: + + from PIL import Image, ImageDraw, ImageFont + + font = ImageFont.truetype("Tests/fonts/FreeMono.ttf") + left, top, right, bottom = font.getbbox("Hello world") + width, height = right - left, bottom - top + + im = Image.new("RGB", (100, 100)) + draw = ImageDraw.Draw(im) + width = draw.textlength("Hello world") + + left, top, right, bottom = draw.multiline_textbbox((0, 0), "Hello\nworld") + width, height = right - left, bottom - top + FreeTypeFont.getmask2 fill parameter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/reference/ImageDraw.rst b/docs/reference/ImageDraw.rst index 43a5a2bc2..aec7a3ef8 100644 --- a/docs/reference/ImageDraw.rst +++ b/docs/reference/ImageDraw.rst @@ -474,116 +474,6 @@ Methods .. versionadded:: 8.0.0 -.. py:method:: ImageDraw.textsize(text, font=None, spacing=4, direction=None, features=None, language=None, stroke_width=0) - - .. deprecated:: 9.2.0 - - See :ref:`deprecations ` for more information. - - Use :py:meth:`textlength()` to measure the offset of following text with - 1/64 pixel precision. - Use :py:meth:`textbbox()` to get the exact bounding box based on an anchor. - - Return the size of the given string, in pixels. - - .. note:: For historical reasons this function measures text height from - the ascender line instead of the top, see :ref:`text-anchors`. - If you wish to measure text height from the top, it is recommended - to use :meth:`textbbox` with ``anchor='lt'`` instead. - - :param text: Text to be measured. If it contains any newline characters, - the text is passed on to :py:meth:`~PIL.ImageDraw.ImageDraw.multiline_textsize`. - :param font: An :py:class:`~PIL.ImageFont.ImageFont` instance. - :param spacing: If the text is passed on to - :py:meth:`~PIL.ImageDraw.ImageDraw.multiline_textsize`, - the number of pixels between lines. - :param direction: Direction of the text. It can be ``"rtl"`` (right to - left), ``"ltr"`` (left to right) or ``"ttb"`` (top to bottom). - Requires libraqm. - - .. versionadded:: 4.2.0 - :param features: A list of OpenType font features to be used during text - layout. This is usually used to turn on optional - font features that are not enabled by default, - for example ``"dlig"`` or ``"ss01"``, but can be also - used to turn off default font features, for - example ``"-liga"`` to disable ligatures or ``"-kern"`` - to disable kerning. To get all supported - features, see `OpenType docs`_. - Requires libraqm. - - .. versionadded:: 4.2.0 - :param language: Language of the text. Different languages may use - different glyph shapes or ligatures. This parameter tells - the font which language the text is in, and to apply the - correct substitutions as appropriate, if available. - It should be a `BCP 47 language code`_. - Requires libraqm. - - .. versionadded:: 6.0.0 - - :param stroke_width: The width of the text stroke. - - .. versionadded:: 6.2.0 - - :return: (width, height) - -.. py:method:: ImageDraw.multiline_textsize(text, font=None, spacing=4, direction=None, features=None, language=None, stroke_width=0) - - .. deprecated:: 9.2.0 - - See :ref:`deprecations ` for more information. - - Use :py:meth:`.multiline_textbbox` instead. - - Return the size of the given string, in pixels. - - Use :py:meth:`textlength()` to measure the offset of following text with - 1/64 pixel precision. - Use :py:meth:`textbbox()` to get the exact bounding box based on an anchor. - - .. note:: For historical reasons this function measures text height as the - distance between the top ascender line and bottom descender line, - not the top and bottom of the text, see :ref:`text-anchors`. - If you wish to measure text height from the top to the bottom of text, - it is recommended to use :meth:`multiline_textbbox` instead. - - :param text: Text to be measured. - :param font: An :py:class:`~PIL.ImageFont.ImageFont` instance. - :param spacing: The number of pixels between lines. - :param direction: Direction of the text. It can be ``"rtl"`` (right to - left), ``"ltr"`` (left to right) or ``"ttb"`` (top to bottom). - Requires libraqm. - - .. versionadded:: 4.2.0 - - :param features: A list of OpenType font features to be used during text - layout. This is usually used to turn on optional - font features that are not enabled by default, - for example ``"dlig"`` or ``"ss01"``, but can be also - used to turn off default font features, for - example ``"-liga"`` to disable ligatures or ``"-kern"`` - to disable kerning. To get all supported - features, see `OpenType docs`_. - Requires libraqm. - - .. versionadded:: 4.2.0 - - :param language: Language of the text. Different languages may use - different glyph shapes or ligatures. This parameter tells - the font which language the text is in, and to apply the - correct substitutions as appropriate, if available. - It should be a `BCP 47 language code`_. - Requires libraqm. - - .. versionadded:: 6.0.0 - - :param stroke_width: The width of the text stroke. - - .. versionadded:: 6.2.0 - - :return: (width, height) - .. py:method:: ImageDraw.textlength(text, font=None, direction=None, features=None, language=None, embedded_color=False) Returns length (in pixels with 1/64 precision) of given text when rendered diff --git a/docs/releasenotes/10.0.0.rst b/docs/releasenotes/10.0.0.rst index cd0296e3e..3ee1a9973 100644 --- a/docs/releasenotes/10.0.0.rst +++ b/docs/releasenotes/10.0.0.rst @@ -82,6 +82,22 @@ FitsStubImagePlugin The stub image plugin ``FitsStubImagePlugin`` has been removed. FITS images can be read without a handler through :mod:`~PIL.FitsImagePlugin` instead. +Font size and offset methods +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Several functions for computing the size and offset of rendered text have been removed: + +=============================================================== ============================================================================================================= +Removed Use instead +=============================================================== ============================================================================================================= +``FreeTypeFont.getsize()`` and ``FreeTypeFont.getoffset()`` :py:meth:`.FreeTypeFont.getbbox` and :py:meth:`.FreeTypeFont.getlength` +``FreeTypeFont.getsize_multiline()`` :py:meth:`.ImageDraw.multiline_textbbox` +``ImageFont.getsize()`` :py:meth:`.ImageFont.getbbox` and :py:meth:`.ImageFont.getlength` +``TransposedFont.getsize()`` :py:meth:`.TransposedFont.getbbox` and :py:meth:`.TransposedFont.getlength` +``ImageDraw.textsize()`` and ``ImageDraw.multiline_textsize()`` :py:meth:`.ImageDraw.textbbox`, :py:meth:`.ImageDraw.textlength` and :py:meth:`.ImageDraw.multiline_textbbox` +``ImageDraw2.Draw.textsize()`` :py:meth:`.ImageDraw2.Draw.textbbox` and :py:meth:`.ImageDraw2.Draw.textlength` +=============================================================== ============================================================================================================= + FreeTypeFont.getmask2 fill parameter ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/releasenotes/9.2.0.rst b/docs/releasenotes/9.2.0.rst index 3dfb25840..8d8bfc9f8 100644 --- a/docs/releasenotes/9.2.0.rst +++ b/docs/releasenotes/9.2.0.rst @@ -48,16 +48,16 @@ Font size and offset methods Several functions for computing the size and offset of rendered text have been deprecated and will be removed in Pillow 10 (2023-07-01): -=========================================================================== ============================================================================================================= -Deprecated Use instead -=========================================================================== ============================================================================================================= -:py:meth:`.FreeTypeFont.getsize` and :py:meth:`.FreeTypeFont.getoffset` :py:meth:`.FreeTypeFont.getbbox` and :py:meth:`.FreeTypeFont.getlength` -:py:meth:`.FreeTypeFont.getsize_multiline` :py:meth:`.ImageDraw.multiline_textbbox` -:py:meth:`.ImageFont.getsize` :py:meth:`.ImageFont.getbbox` and :py:meth:`.ImageFont.getlength` -:py:meth:`.TransposedFont.getsize` :py:meth:`.TransposedFont.getbbox` and :py:meth:`.TransposedFont.getlength` -:py:meth:`.ImageDraw.textsize` and :py:meth:`.ImageDraw.multiline_textsize` :py:meth:`.ImageDraw.textbbox`, :py:meth:`.ImageDraw.textlength` and :py:meth:`.ImageDraw.multiline_textbbox` -:py:meth:`.ImageDraw2.Draw.textsize` :py:meth:`.ImageDraw2.Draw.textbbox` and :py:meth:`.ImageDraw2.Draw.textlength` -=========================================================================== ============================================================================================================= +=============================================================== ============================================================================================================= +Deprecated Use instead +=============================================================== ============================================================================================================= +``FreeTypeFont.getsize()`` and ``FreeTypeFont.getoffset()`` :py:meth:`.FreeTypeFont.getbbox` and :py:meth:`.FreeTypeFont.getlength` +``FreeTypeFont.getsize_multiline()`` :py:meth:`.ImageDraw.multiline_textbbox` +``ImageFont.getsize()`` :py:meth:`.ImageFont.getbbox` and :py:meth:`.ImageFont.getlength` +``TransposedFont.getsize()`` :py:meth:`.TransposedFont.getbbox` and :py:meth:`.TransposedFont.getlength` +``ImageDraw.textsize()`` and ``ImageDraw.multiline_textsize()`` :py:meth:`.ImageDraw.textbbox`, :py:meth:`.ImageDraw.textlength` and :py:meth:`.ImageDraw.multiline_textbbox` +``ImageDraw2.Draw.textsize()`` :py:meth:`.ImageDraw2.Draw.textbbox` and :py:meth:`.ImageDraw2.Draw.textlength` +=============================================================== ============================================================================================================= Previous code:: diff --git a/src/PIL/ImageDraw.py b/src/PIL/ImageDraw.py index 8adcc87de..e9ccf8041 100644 --- a/src/PIL/ImageDraw.py +++ b/src/PIL/ImageDraw.py @@ -32,10 +32,8 @@ import math import numbers -import warnings from . import Image, ImageColor -from ._deprecate import deprecate """ A simple 2D drawing interface for PIL images. @@ -433,17 +431,11 @@ class ImageDraw: return text.split(split_character) def _multiline_spacing(self, font, spacing, stroke_width): - # this can be replaced with self.textbbox(...)[3] when textsize is removed - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=DeprecationWarning) - return ( - self.textsize( - "A", - font=font, - stroke_width=stroke_width, - )[1] - + spacing - ) + return ( + self.textbbox((0, 0), "A", font, stroke_width=stroke_width)[3] + + stroke_width + + spacing + ) def text( self, @@ -645,72 +637,6 @@ class ImageDraw: ) top += line_spacing - def textsize( - self, - text, - font=None, - spacing=4, - direction=None, - features=None, - language=None, - stroke_width=0, - ): - """Get the size of a given string, in pixels.""" - deprecate("textsize", 10, "textbbox or textlength") - if self._multiline_check(text): - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=DeprecationWarning) - return self.multiline_textsize( - text, - font, - spacing, - direction, - features, - language, - stroke_width, - ) - - if font is None: - font = self.getfont() - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=DeprecationWarning) - return font.getsize( - text, - direction, - features, - language, - stroke_width, - ) - - def multiline_textsize( - self, - text, - font=None, - spacing=4, - direction=None, - features=None, - language=None, - stroke_width=0, - ): - deprecate("multiline_textsize", 10, "multiline_textbbox") - max_width = 0 - lines = self._multiline_split(text) - line_spacing = self._multiline_spacing(font, spacing, stroke_width) - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=DeprecationWarning) - for line in lines: - line_width, line_height = self.textsize( - line, - font, - spacing, - direction, - features, - language, - stroke_width, - ) - max_width = max(max_width, line_width) - return max_width, len(lines) * line_spacing - spacing - def textlength( self, text, @@ -731,22 +657,7 @@ class ImageDraw: if font is None: font = self.getfont() mode = "RGBA" if embedded_color else self.fontmode - try: - return font.getlength(text, mode, direction, features, language) - except AttributeError: - deprecate("textlength support for fonts without getlength", 10) - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=DeprecationWarning) - size = self.textsize( - text, - font, - direction=direction, - features=features, - language=language, - ) - if direction == "ttb": - return size[1] - return size[0] + return font.getlength(text, mode, direction, features, language) def textbbox( self, diff --git a/src/PIL/ImageDraw2.py b/src/PIL/ImageDraw2.py index 2667b77dd..7ce0224a6 100644 --- a/src/PIL/ImageDraw2.py +++ b/src/PIL/ImageDraw2.py @@ -24,10 +24,7 @@ """ -import warnings - from . import Image, ImageColor, ImageDraw, ImageFont, ImagePath -from ._deprecate import deprecate class Pen: @@ -173,19 +170,6 @@ class Draw: xy.transform(self.transform) self.draw.text(xy, text, font=font.font, fill=font.color) - def textsize(self, text, font): - """ - .. deprecated:: 9.2.0 - - Return the size of the given string, in pixels. - - .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.textsize` - """ - deprecate("textsize", 10, "textbbox or textlength") - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=DeprecationWarning) - return self.draw.textsize(text, font=font.font) - def textbbox(self, xy, text, font): """ Returns bounding box (in pixels) of given text. diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py index e7d45636c..ea4549cf5 100644 --- a/src/PIL/ImageFont.py +++ b/src/PIL/ImageFont.py @@ -34,7 +34,6 @@ from enum import IntEnum from io import BytesIO from . import Image -from ._deprecate import deprecate from ._util import is_directory, is_path @@ -120,23 +119,6 @@ class ImageFont: self.font = Image.core.font(image.im, data) - def getsize(self, text, *args, **kwargs): - """ - .. deprecated:: 9.2.0 - - Use :py:meth:`.getbbox` or :py:meth:`.getlength` instead. - - See :ref:`deprecations ` for more information. - - Returns width and height (in pixels) of given text. - - :param text: Text to measure. - - :return: (width, height) - """ - deprecate("getsize", 10, "getbbox or getlength") - return self.font.getsize(text) - def getmask(self, text, mode="", *args, **kwargs): """ Create a bitmap for the text. @@ -398,165 +380,6 @@ class FreeTypeFont: width, height = size[0] + 2 * stroke_width, size[1] + 2 * stroke_width return left, top, left + width, top + height - def getsize( - self, - text, - direction=None, - features=None, - language=None, - stroke_width=0, - ): - """ - .. deprecated:: 9.2.0 - - Use :py:meth:`getlength()` to measure the offset of following text with - 1/64 pixel precision. - Use :py:meth:`getbbox()` to get the exact bounding box based on an anchor. - - See :ref:`deprecations ` for more information. - - Returns width and height (in pixels) of given text if rendered in font with - provided direction, features, and language. - - .. note:: For historical reasons this function measures text height from - the ascender line instead of the top, see :ref:`text-anchors`. - If you wish to measure text height from the top, it is recommended - to use the bottom value of :meth:`getbbox` with ``anchor='lt'`` instead. - - :param text: Text to measure. - - :param direction: Direction of the text. It can be 'rtl' (right to - left), 'ltr' (left to right) or 'ttb' (top to bottom). - Requires libraqm. - - .. versionadded:: 4.2.0 - - :param features: A list of OpenType font features to be used during text - layout. This is usually used to turn on optional - font features that are not enabled by default, - for example 'dlig' or 'ss01', but can be also - used to turn off default font features for - example '-liga' to disable ligatures or '-kern' - to disable kerning. To get all supported - features, see - https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist - Requires libraqm. - - .. versionadded:: 4.2.0 - - :param language: Language of the text. Different languages may use - different glyph shapes or ligatures. This parameter tells - the font which language the text is in, and to apply the - correct substitutions as appropriate, if available. - It should be a `BCP 47 language code - `_ - Requires libraqm. - - .. versionadded:: 6.0.0 - - :param stroke_width: The width of the text stroke. - - .. versionadded:: 6.2.0 - - :return: (width, height) - """ - deprecate("getsize", 10, "getbbox or getlength") - # vertical offset is added for historical reasons - # see https://github.com/python-pillow/Pillow/pull/4910#discussion_r486682929 - size, offset = self.font.getsize(text, "L", direction, features, language) - return ( - size[0] + stroke_width * 2, - size[1] + stroke_width * 2 + offset[1], - ) - - def getsize_multiline( - self, - text, - direction=None, - spacing=4, - features=None, - language=None, - stroke_width=0, - ): - """ - .. deprecated:: 9.2.0 - - Use :py:meth:`.ImageDraw.multiline_textbbox` instead. - - See :ref:`deprecations ` for more information. - - Returns width and height (in pixels) of given text if rendered in font - with provided direction, features, and language, while respecting - newline characters. - - :param text: Text to measure. - - :param direction: Direction of the text. It can be 'rtl' (right to - left), 'ltr' (left to right) or 'ttb' (top to bottom). - Requires libraqm. - - :param spacing: The vertical gap between lines, defaulting to 4 pixels. - - :param features: A list of OpenType font features to be used during text - layout. This is usually used to turn on optional - font features that are not enabled by default, - for example 'dlig' or 'ss01', but can be also - used to turn off default font features for - example '-liga' to disable ligatures or '-kern' - to disable kerning. To get all supported - features, see - https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist - Requires libraqm. - - :param language: Language of the text. Different languages may use - different glyph shapes or ligatures. This parameter tells - the font which language the text is in, and to apply the - correct substitutions as appropriate, if available. - It should be a `BCP 47 language code - `_ - Requires libraqm. - - .. versionadded:: 6.0.0 - - :param stroke_width: The width of the text stroke. - - .. versionadded:: 6.2.0 - - :return: (width, height) - """ - deprecate("getsize_multiline", 10, "ImageDraw.multiline_textbbox") - max_width = 0 - lines = self._multiline_split(text) - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=DeprecationWarning) - line_spacing = self.getsize("A", stroke_width=stroke_width)[1] + spacing - for line in lines: - line_width, line_height = self.getsize( - line, direction, features, language, stroke_width - ) - max_width = max(max_width, line_width) - - return max_width, len(lines) * line_spacing - spacing - - def getoffset(self, text): - """ - .. deprecated:: 9.2.0 - - Use :py:meth:`.getbbox` instead. - - See :ref:`deprecations ` for more information. - - Returns the offset of given text. This is the gap between the - starting coordinate and the first marking. Note that this gap is - included in the result of :py:func:`~PIL.ImageFont.FreeTypeFont.getsize`. - - :param text: Text to measure. - - :return: A tuple of the x and y offset - """ - deprecate("getoffset", 10, "getbbox") - return self.font.getsize(text)[1] - def getmask( self, text, @@ -851,22 +674,6 @@ class TransposedFont: self.font = font self.orientation = orientation # any 'transpose' argument, or None - def getsize(self, text, *args, **kwargs): - """ - .. deprecated:: 9.2.0 - - Use :py:meth:`.getbbox` or :py:meth:`.getlength` instead. - - See :ref:`deprecations ` for more information. - """ - deprecate("getsize", 10, "getbbox or getlength") - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=DeprecationWarning) - w, h = self.font.getsize(text) - if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270): - return h, w - return w, h - def getmask(self, text, mode="", *args, **kwargs): im = self.font.getmask(text, mode, *args, **kwargs) if self.orientation is not None: diff --git a/src/PIL/_deprecate.py b/src/PIL/_deprecate.py index 81f2189dc..2f2a3df13 100644 --- a/src/PIL/_deprecate.py +++ b/src/PIL/_deprecate.py @@ -45,8 +45,6 @@ def deprecate( elif when <= int(__version__.split(".")[0]): msg = f"{deprecated} {is_} deprecated and should be removed." raise RuntimeError(msg) - elif when == 10: - removed = "Pillow 10 (2023-07-01)" elif when == 11: removed = "Pillow 11 (2024-10-15)" else: