From aefb04fff03ae0cb6a1c30745c1d841769c2e8dc Mon Sep 17 00:00:00 2001 From: nulano Date: Wed, 22 Jul 2020 22:07:42 +0200 Subject: [PATCH] restore and document previous getsize behaviour see discussion in issue 4789 --- Tests/test_imagefont.py | 5 ++++- docs/reference/ImageDraw.rst | 9 +++++++++ src/PIL/ImageFont.py | 22 +++++++++++++++------- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index e58945524..79f31316b 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -37,18 +37,21 @@ class TestImageFont: (">=2.3", "<2.4"): { "multiline": 30, "textsize": 12, + "getters": (13, 16), "multiline-anchor": 6, "getlength": (36, 27, 27, 33), }, (">=2.7",): { "multiline": 6.2, "textsize": 2.5, + "getters": (12, 16), "multiline-anchor": 4, "getlength": (36, 21, 24, 33), }, "Default": { "multiline": 0.5, "textsize": 0.5, + "getters": (12, 16), "multiline-anchor": 4, "getlength": (36, 24, 24, 33), }, @@ -624,7 +627,7 @@ class TestImageFont: assert t.font.glyphs == 4177 assert t.getsize("A") == (12, 16) assert t.getsize("AB") == (24, 16) - assert t.getsize("M") == (12, 16) + assert t.getsize("M") == self.metrics["getters"] assert t.getsize("y") == (12, 20) assert t.getsize("a") == (12, 16) assert t.getsize_multiline("A") == (12, 16) diff --git a/docs/reference/ImageDraw.rst b/docs/reference/ImageDraw.rst index 9fca33a01..612d27cc1 100644 --- a/docs/reference/ImageDraw.rst +++ b/docs/reference/ImageDraw.rst @@ -386,6 +386,15 @@ Methods Return the size of the given string, in pixels. + You can use :meth:`.FreeTypeFont.getlength` to measure text length + with 1/64 pixel precision. + + .. 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:`.FreeTypeFont.getbbox` 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. diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py index 533f239c4..174e3bfe7 100644 --- a/src/PIL/ImageFont.py +++ b/src/PIL/ImageFont.py @@ -217,8 +217,8 @@ class FreeTypeFont: def getlength(self, text, mode="", direction=None, features=None, language=None): """ - Returns length (in pixels) of given text if rendered in font with - provided direction, features, and language. + Returns length (in pixels with 1/64 precision) of given text if rendered + in font with provided direction, features, and language. This is the amount by which following text should be offset. Text bounding box may extend past the length in some fonts, @@ -275,8 +275,9 @@ class FreeTypeFont: Returns bounding box (in pixels) of given text relative to given anchor if rendered in font with provided direction, features, and language. - Use :py:func`getlength()` to get the offset of following text. The bounding - box includes extra margins for some fonts, e.g. italics or accents. + Use :py:meth`getlength()` to get the offset of following text with + 1/64 pixel precision. The bounding box includes extra margins for + some fonts, e.g. italics or accents. :param text: Text to render. :param mode: Used by some graphics drivers to indicate what mode the @@ -329,8 +330,14 @@ class FreeTypeFont: Returns width and height (in pixels) of given text if rendered in font with provided direction, features, and language. - Use :py:func:`getlength()` to measure the offset of following text. - Use :py:func:`getbbox()` to get the exact bounding box based on an anchor. + 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. + + .. 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:`getbbox` with `anchor='lt'` instead. :param text: Text to measure. @@ -369,9 +376,10 @@ class FreeTypeFont: :return: (width, height) """ + # vertical offset is added for historical reasons, see discussion in #4789 size, offset = self.font.getsize(text, False, direction, features, language) return ( - size[0] + stroke_width * 2 + offset[0], + size[0] + stroke_width * 2, size[1] + stroke_width * 2 + offset[1], )