mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-11 04:07:21 +03:00
Merge pull request #7080 from radarhere/getsize
Remove deprecated ImageFont.getsize and related functions for Pillow 10.0.0
This commit is contained in:
commit
0b9997f41b
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -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 <Font size and offset methods>` 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 <Font size and offset methods>` 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
|
||||
|
|
|
@ -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
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -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::
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 <Font size and offset methods>` 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 <Font size and offset methods>` 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
|
||||
<https://www.w3.org/International/articles/language-tags/>`_
|
||||
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 <Font size and offset methods>` 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
|
||||
<https://www.w3.org/International/articles/language-tags/>`_
|
||||
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 <Font size and offset methods>` 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 <Font size and offset methods>` 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:
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue
Block a user