From 6a58a1c93e739f5e9f13eb18cc21af7628c40a6d Mon Sep 17 00:00:00 2001 From: Alexander Schier Date: Sat, 29 Mar 2014 00:47:17 +0100 Subject: [PATCH 1/2] added support for multiline text drawing --- PIL/ImageDraw.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/PIL/ImageDraw.py b/PIL/ImageDraw.py index a03d26016..193e3a7a6 100644 --- a/PIL/ImageDraw.py +++ b/PIL/ImageDraw.py @@ -256,6 +256,9 @@ class ImageDraw: # Draw text. def text(self, xy, text, fill=None, font=None, anchor=None): + if "\n" in text: + return self.multiline_text(xy, text, fill, font, anchor) + ink, fill = self._getink(fill) if font is None: font = self.getfont() @@ -272,10 +275,49 @@ class ImageDraw: 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 + lines = text.split("\n") + 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 either "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 = text.split("\n") + 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 "\n" in text: + return multiline_textsize(text, font) + if font is None: font = self.getfont() return font.getsize(text) From 3aa718002caebbc82ad2f4177b5c82d51583f209 Mon Sep 17 00:00:00 2001 From: allo Date: Tue, 8 Apr 2014 19:16:22 +0200 Subject: [PATCH 2/2] changed multiline text spacing from pixels to em the spacing is now a float, which will be multiplied with the width of a letter "m" in the chosen font. --- PIL/ImageDraw.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PIL/ImageDraw.py b/PIL/ImageDraw.py index 193e3a7a6..c2417589e 100644 --- a/PIL/ImageDraw.py +++ b/PIL/ImageDraw.py @@ -279,6 +279,10 @@ class ImageDraw: 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 = text.split("\n") for line in lines: line_width, line_height = self.textsize(line, font)