From 9ce3eba7eb8190b04f29830beba1253bd26fe1d7 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 22 Feb 2021 07:38:04 +1100 Subject: [PATCH] Only draw each pixel once --- .../imagedraw_rounded_rectangle_both.png | Bin 0 -> 530 bytes .../images/imagedraw_rounded_rectangle_x.png | Bin 0 -> 567 bytes .../images/imagedraw_rounded_rectangle_y.png | Bin 0 -> 528 bytes Tests/test_imagedraw.py | 24 ++++ src/PIL/ImageDraw.py | 103 +++++++++++++----- 5 files changed, 98 insertions(+), 29 deletions(-) create mode 100644 Tests/images/imagedraw_rounded_rectangle_both.png create mode 100644 Tests/images/imagedraw_rounded_rectangle_x.png create mode 100644 Tests/images/imagedraw_rounded_rectangle_y.png diff --git a/Tests/images/imagedraw_rounded_rectangle_both.png b/Tests/images/imagedraw_rounded_rectangle_both.png new file mode 100644 index 0000000000000000000000000000000000000000..24f600e3913ebc74a9c301e815f06f4ac0cfdd94 GIT binary patch literal 530 zcmeAS@N?(olHy`uVBq!ia0vp^DIm7ZFWD}C_M}wCs{)<;eRDP)o0Zj@@g?*-%YXh2Cub>!tu2gw`02!~<0084 z-RnK1`%I^)u!s%^Wrko*Ci z>}`Huu3gs7ZhQOk`^z=c%tQ=M%qsIWS=Y?1;;o>R-BzHQ_2I-V^_n&7FNirrZ+iA| z>TR8qb5tKpF?HUtsJZ~?m)F{Rqb-XLEvk_Jv-s5<*OYTsYmCGKebp|D?4uWRojEl-z|T`s&ch> literal 0 HcmV?d00001 diff --git a/Tests/images/imagedraw_rounded_rectangle_x.png b/Tests/images/imagedraw_rounded_rectangle_x.png new file mode 100644 index 0000000000000000000000000000000000000000..4bf5211a3340d62724b64a5517693c1fa2403e7d GIT binary patch literal 567 zcmeAS@N?(olHy`uVBq!ia0vp^DImsnv^Py)@I#H6G!aHYxGIp1VMO3=9uSE2Lu&$j^^gx8G4e{Yv2p zkI3asQ9VNDZr3i)l3N)brgi#JhWE^^-xt*;EnB3$euc-isrH`>r}fR}?p~rSHoY|G z)s>6WlCuNjBO`T#{Vi@?+BEI6=#;J5rxv}O7@MjXzmj?1v5@Su7beP23{88L@U%t0 zUOI2}narq-xt{scwG|aEzKp7;#;jQ_5L91BvpZlrp`NrOe<1yh3&3|zc8+e-t_F_ zROyHVGgTi<0ZJ_@HaK%q>b175p^DMd6%}G<*JfP{d~)X2S|jm|n^pz@L+woX(?2?D zn>h_W`!{4xVk&ixUF^)86}S4T?ZM~&{BLr5q-k>-Y>jTH`~Z%~^+)udCACbFI5_JE Oi0|p@=d#Wzp$Pyx_3|kI literal 0 HcmV?d00001 diff --git a/Tests/images/imagedraw_rounded_rectangle_y.png b/Tests/images/imagedraw_rounded_rectangle_y.png new file mode 100644 index 0000000000000000000000000000000000000000..9b391b95e28ea723f75e90210945f1481d93d402 GIT binary patch literal 528 zcmeAS@N?(olHy`uVBq!ia0vp^DIm37 zx6T&5yXNj1ekQKN^_ScyZq&GA?4T4MP&VO)CM!@M7`Rka-?Xl+W8L@TeEEa!|J}W! zQZKw>cC3i#Pr23Q@l59RM>qGrtM~54Wu6K;S{iCM`Re8c{U?e)bai zaw}?Hd1Vm3RHWIrXHFfVaZ&s7&=$$1nAL zofUm1{en% z&%y@vNY;7$Q~ax)mtGGqnm7N!^FOmL6o&p;-`r5oBlscS1QtCv}Ao?m#zm1 NdAj= x1 - x0 + if full_x: + # The two left and two right corners are joined + d = x1 - x0 + full_y = d >= y1 - y0 + if full_y: + # The two top and two bottom corners are joined + d = y1 - y0 + if full_x and full_y: + # If all corners are joined, that is a circle + return self.ellipse(xy, fill, outline, width) + if d == 0: + # If the corners have no curve, that is a rectangle return self.rectangle(xy, fill, outline, width) ink, fill = self._getink(outline, fill) + + def draw_corners(pieslice): + if full_x: + # Draw top and bottom halves + parts = ( + ((x0, y0, x0 + d, y0 + d), 180, 360), + ((x0, y1 - d, x0 + d, y1), 0, 180), + ) + elif full_y: + # Draw left and right halves + parts = ( + ((x0, y0, x0 + d, y0 + d), 90, 270), + ((x1 - d, y0, x1, y0 + d), 270, 90), + ) + else: + # Draw four separate corners + parts = ( + ((x1 - d, y0, x1, y0 + d), 270, 360), + ((x1 - d, y1 - d, x1, y1), 0, 90), + ((x0, y1 - d, x0 + d, y1), 90, 180), + ((x0, y0, x0 + d, y0 + d), 180, 270), + ) + for part in parts: + if pieslice: + self.draw.draw_pieslice(*(part + (fill, 1))) + else: + self.draw.draw_arc(*(part + (ink, width))) + if fill is not None: - self.draw.draw_pieslice((x1 - d, y0, x1, y0 + d), 270, 360, fill, 1) - self.draw.draw_pieslice((x1 - d, y1 - d, x1, y1), 0, 90, fill, 1) - self.draw.draw_pieslice((x0, y1 - d, x0 + d, y1), 90, 180, fill, 1) - self.draw.draw_pieslice((x0, y0, x0 + d, y0 + d), 180, 270, fill, 1) + draw_corners(True) - self.draw.draw_rectangle((x0 + d / 2 + 1, y0, x1 - d / 2 - 1, y1), fill, 1) - self.draw.draw_rectangle( - (x0, y0 + d / 2 + 1, x0 + d / 2, y1 - d / 2 - 1), fill, 1 - ) - self.draw.draw_rectangle( - (x1 - d / 2, y0 + d / 2 + 1, x1, y1 - d / 2 - 1), fill, 1 - ) + if full_x: + self.draw.draw_rectangle( + (x0, y0 + d / 2 + 1, x1, y1 - d / 2 - 1), fill, 1 + ) + else: + self.draw.draw_rectangle( + (x0 + d / 2 + 1, y0, x1 - d / 2 - 1, y1), fill, 1 + ) + if not full_x and not full_y: + self.draw.draw_rectangle( + (x0, y0 + d / 2 + 1, x0 + d / 2, y1 - d / 2 - 1), fill, 1 + ) + self.draw.draw_rectangle( + (x1 - d / 2, y0 + d / 2 + 1, x1, y1 - d / 2 - 1), fill, 1 + ) if ink is not None and ink != fill and width != 0: - self.draw.draw_arc((x1 - d, y0, x1, y0 + d), 270, 360, ink, width) - self.draw.draw_arc((x1 - d, y1 - d, x1, y1), 0, 90, ink, width) - self.draw.draw_arc((x0, y1 - d, x0 + d, y1), 90, 180, ink, width) - self.draw.draw_arc((x0, y0, x0 + d, y0 + d), 180, 270, ink, width) + draw_corners(False) - self.draw.draw_rectangle( - (x1 - width + 1, y0 + d / 2 + 1, x1, y1 - d / 2 - 1), ink, 1 - ) - self.draw.draw_rectangle( - (x0 + d / 2 + 1, y1 - width + 1, x1 - d / 2 - 1, y1), ink, 1 - ) - self.draw.draw_rectangle( - (x0, y0 + d / 2 + 1, x0 + width - 1, y1 - d / 2 - 1), ink, 1 - ) - self.draw.draw_rectangle( - (x0 + d / 2 + 1, y0, x1 - d / 2 - 1, y0 + width - 1), ink, 1 - ) + if not full_x: + self.draw.draw_rectangle( + (x0 + d / 2 + 1, y0, x1 - d / 2 - 1, y0 + width - 1), ink, 1 + ) + self.draw.draw_rectangle( + (x0 + d / 2 + 1, y1 - width + 1, x1 - d / 2 - 1, y1), ink, 1 + ) + if not full_y: + self.draw.draw_rectangle( + (x0, y0 + d / 2 + 1, x0 + width - 1, y1 - d / 2 - 1), ink, 1 + ) + self.draw.draw_rectangle( + (x1 - width + 1, y0 + d / 2 + 1, x1, y1 - d / 2 - 1), ink, 1 + ) def _multiline_check(self, text): """Draw text."""