mirror of
https://github.com/python-pillow/Pillow.git
synced 2026-02-04 22:39:33 +03:00
Added wrap()
This commit is contained in:
parent
374957cefd
commit
9ac4edc54b
|
|
@ -108,3 +108,20 @@ def test_stroke() -> None:
|
|||
assert_image_similar_tofile(
|
||||
im, "Tests/images/imagedraw_stroke_" + suffix + ".png", 3.1
|
||||
)
|
||||
|
||||
|
||||
def test_wrap() -> None:
|
||||
# No wrap required
|
||||
text = ImageText.Text("Hello World!")
|
||||
text.wrap(100)
|
||||
assert text.text == "Hello World!"
|
||||
|
||||
# Wrap word to a new line
|
||||
text = ImageText.Text("Hello World!")
|
||||
text.wrap(50)
|
||||
assert text.text == "Hello\nWorld!"
|
||||
|
||||
# Split word across lines
|
||||
text = ImageText.Text("Hello World!")
|
||||
text.wrap(25)
|
||||
assert text.text == "Hello\nWorl\nd!"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import cast
|
||||
|
||||
from . import ImageFont
|
||||
from ._typing import _Ink
|
||||
|
||||
|
|
@ -88,6 +90,70 @@ class Text:
|
|||
else:
|
||||
return "L"
|
||||
|
||||
def wrap(self, width: int) -> None:
|
||||
str_type = isinstance(self.text, str)
|
||||
wrapped_lines = []
|
||||
emptystring = "" if str_type else b""
|
||||
fontmode = self._get_fontmode()
|
||||
for line in self.text.splitlines():
|
||||
wrapped_line = emptystring
|
||||
words = line.split()
|
||||
while words:
|
||||
word = words[0]
|
||||
|
||||
new_wrapped_line: str | bytes
|
||||
if wrapped_line:
|
||||
if str_type:
|
||||
new_wrapped_line = (
|
||||
cast(str, wrapped_line) + " " + cast(str, word)
|
||||
)
|
||||
else:
|
||||
new_wrapped_line = (
|
||||
cast(bytes, wrapped_line) + b" " + cast(bytes, word)
|
||||
)
|
||||
else:
|
||||
new_wrapped_line = word
|
||||
|
||||
def get_width(text) -> float:
|
||||
left, _, right, _ = self.font.getbbox(
|
||||
text,
|
||||
fontmode,
|
||||
self.direction,
|
||||
self.features,
|
||||
self.language,
|
||||
self.stroke_width,
|
||||
)
|
||||
return right - left
|
||||
|
||||
if get_width(new_wrapped_line) > width:
|
||||
if wrapped_line:
|
||||
wrapped_lines.append(wrapped_line)
|
||||
wrapped_line = emptystring
|
||||
else:
|
||||
# This word is too long for a single line, so split the word
|
||||
characters = word
|
||||
i = len(characters)
|
||||
while i > 1 and get_width(characters[:i]) > width:
|
||||
i -= 1
|
||||
wrapped_line = characters[:i]
|
||||
if str_type:
|
||||
cast(list[str], words)[0] = cast(str, characters[i:])
|
||||
else:
|
||||
cast(list[bytes], words)[0] = cast(bytes, characters[i:])
|
||||
else:
|
||||
words.pop(0)
|
||||
wrapped_line = new_wrapped_line
|
||||
if wrapped_line:
|
||||
wrapped_lines.append(wrapped_line)
|
||||
if str_type:
|
||||
self.text = "\n".join(
|
||||
[line for line in wrapped_lines if isinstance(line, str)]
|
||||
)
|
||||
else:
|
||||
self.text = b"\n".join(
|
||||
[line for line in wrapped_lines if isinstance(line, bytes)]
|
||||
)
|
||||
|
||||
def get_length(self) -> float:
|
||||
"""
|
||||
Returns length (in pixels with 1/64 precision) of text.
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user