Skip to content

Commit

Permalink
Merge 05c9a82 into 40165d6
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Apr 23, 2015
2 parents 40165d6 + 05c9a82 commit 8a9d69d
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
54 changes: 54 additions & 0 deletions PIL/ImageDraw.py
Expand Up @@ -256,7 +256,20 @@ def rectangle(self, xy, fill=None, outline=None):
##
# Draw text.

def _multiline_check(self, text):
split_character = "\n" if type(text) == type("") else b"\n"

return split_character in text

def _multiline_split(self, text):
split_character = "\n" if type(text) == type("") else b"\n"

return text.split(split_character)

def text(self, xy, text, fill=None, font=None, anchor=None):
if self._multiline_check(text):
return self.multiline_text(xy, text, fill, font, anchor)

ink, fill = self._getink(fill)
if font is None:
font = self.getfont()
Expand All @@ -273,10 +286,51 @@ def text(self, xy, text, fill=None, font=None, anchor=None):
mask = font.getmask(text)
self.draw.draw_bitmap(xy, mask, ink)

def multiline_text(self, xy, text, fill=None, font=None, anchor=None,
spacing=0, align="left"):
widths, heights = [], []
max_width = 0
# spacing in em (multiples of the width of a "m")
if spacing != 0:
m_width, m_height = self.textsize("m", font)
spacing = float(spacing) * m_width
lines = self._multiline_split(text)
for line in lines:
line_width, line_height = self.textsize(line, font)
widths.append(line_width)
max_width = max(max_width, line_width)
heights.append(line_height)
left, top = xy
for idx, line in enumerate(lines):
if align == "left":
pass # left = x
elif align == "center":
left += (max_width - widths[idx]) / 2.0
elif align == "right":
left += (max_width - widths[idx])
else:
assert False, 'align must be "left", "center" or "right"'
self.text((left, top), line, fill, font, anchor)
top += heights[idx] + spacing
left = xy[0]

def multiline_textsize(self, text, font=None, spacing=0):
max_width = 0
height = 0
lines = self._multiline_split(text)
for line in lines:
line_width, line_height = self.textsize(line, font)
height += line_height + spacing
max_width = max(max_width, line_width)
return max_width, height

##
# Get the size of a given string, in pixels.

def textsize(self, text, font=None):
if self._multiline_check(text):
return self.multiline_textsize(text, font)

if font is None:
font = self.getfont()
return font.getsize(text)
Expand Down
15 changes: 15 additions & 0 deletions Tests/test_imagefont.py
Expand Up @@ -147,6 +147,21 @@ def test_render_multiline(self):
# at epsilon = ~38.
self.assert_image_similar(im, target_img, .5)

def test_render_multiline_text(self):
im = Image.new(mode='RGB', size=(300, 100))
draw = ImageDraw.Draw(im)
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
text = "hey you\nyou are awesome\nthis looks awkward"
draw.text((0, 0), text, font=ttf)

target = 'Tests/images/multiline_text.png'
target_img = Image.open(target)

# some versions of freetype have different horizontal spacing.
# setting a tight epsilon, I'm showing the original test failure
# at epsilon = ~38.
self.assert_image_similar(im, target_img, .5)

def test_rotated_transposed_font(self):
img_grey = Image.new("L", (100, 100))
draw = ImageDraw.Draw(img_grey)
Expand Down

0 comments on commit 8a9d69d

Please sign in to comment.