Skip to content

Commit 1346bfe

Browse files
committed
Allow ImageDraw text() to use ImageText
1 parent 7a2629b commit 1346bfe

File tree

3 files changed

+51
-13
lines changed

3 files changed

+51
-13
lines changed

Tests/test_imagetext.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
import pytest
44

5-
from PIL import ImageFont, ImageText
5+
from PIL import Image, ImageDraw, ImageFont, ImageText
66

7-
from .helper import skip_unless_feature
7+
from .helper import assert_image_similar_tofile, skip_unless_feature
88

99
FONT_PATH = "Tests/fonts/FreeMono.ttf"
1010

@@ -39,3 +39,34 @@ def test_get_bbox(font: ImageFont.FreeTypeFont) -> None:
3939
assert ImageText.ImageText("M", font).get_bbox() == (0, 4, 12, 16)
4040
assert ImageText.ImageText("y", font).get_bbox() == (0, 7, 12, 20)
4141
assert ImageText.ImageText("a", font).get_bbox() == (0, 7, 12, 16)
42+
43+
44+
def test_standard_embedded_color(layout_engine: ImageFont.Layout) -> None:
45+
font = ImageFont.truetype(FONT_PATH, 40, layout_engine=layout_engine)
46+
text = ImageText.ImageText("Hello World!", font)
47+
text.embed_color()
48+
49+
im = Image.new("RGB", (300, 64), "white")
50+
draw = ImageDraw.Draw(im)
51+
draw.text((10, 10), text, "#fa6")
52+
53+
assert_image_similar_tofile(im, "Tests/images/standard_embedded.png", 3.1)
54+
55+
56+
@skip_unless_feature("freetype2")
57+
def test_stroke() -> None:
58+
for suffix, stroke_fill in {"same": None, "different": "#0f0"}.items():
59+
# Arrange
60+
im = Image.new("RGB", (120, 130))
61+
draw = ImageDraw.Draw(im)
62+
font = ImageFont.truetype(FONT_PATH, 120)
63+
text = ImageText.ImageText("A", font)
64+
text.stroke(2, stroke_fill)
65+
66+
# Act
67+
draw.text((12, 12), text, "#f00")
68+
69+
# Assert
70+
assert_image_similar_tofile(
71+
im, "Tests/images/imagedraw_stroke_" + suffix + ".png", 3.1
72+
)

docs/reference/ImageText.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
The :py:mod:`~PIL.ImageText` module defines a class with the same name. Instances of
88
this class provide a way to use fonts with text strings or bytes. The result is a
9-
simple API to apply styling to pieces of text and measure them.
9+
simple API to apply styling to pieces of text and measure or draw them.
1010

1111
Example
1212
-------
@@ -23,6 +23,10 @@ Example
2323
print(text.get_length()) # 154.0
2424
print(text.get_bbox()) # (-2, 3, 156, 22)
2525

26+
im = Image.new("RGB", text.get_bbox()[2:])
27+
d = ImageDraw.Draw(im)
28+
d.text((0, 0), text, "#f00")
29+
2630
Methods
2731
-------
2832

src/PIL/ImageDraw.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ def draw_corners(pieslice: bool) -> None:
537537
def text(
538538
self,
539539
xy: tuple[float, float],
540-
text: AnyStr,
540+
text: AnyStr | ImageText.ImageText,
541541
fill: _Ink | None = None,
542542
font: (
543543
ImageFont.ImageFont
@@ -558,15 +558,18 @@ def text(
558558
**kwargs: Any,
559559
) -> None:
560560
"""Draw text."""
561-
if font is None:
562-
font = self._getfont(kwargs.get("font_size"))
563-
imagetext = ImageText.ImageText(
564-
text, font, self.mode, spacing, direction, features, language
565-
)
566-
if embedded_color:
567-
imagetext.embed_color()
568-
if stroke_width:
569-
imagetext.stroke(stroke_width, stroke_fill)
561+
if isinstance(text, ImageText.ImageText):
562+
imagetext = text
563+
else:
564+
if font is None:
565+
font = self._getfont(kwargs.get("font_size"))
566+
imagetext = ImageText.ImageText(
567+
text, font, self.mode, spacing, direction, features, language
568+
)
569+
if embedded_color:
570+
imagetext.embed_color()
571+
if stroke_width:
572+
imagetext.stroke(stroke_width, stroke_fill)
570573

571574
def getink(fill: _Ink | None) -> int:
572575
ink, fill_ink = self._getink(fill)

0 commit comments

Comments
 (0)