1
0
Fork 0

draw565: Add width to the line drawing function

Currently all lines are a single pixel wide. To draw wider lines we
must draw two parallel lines with a single pixel offset and this is
a *very* inefficient approach, espeically on ST7789 where we spend
longer setting the clipping window than we do drawing each pixel.

Fix this by constructing a line using a variable sized square rather than
a single pixel. This will "overdraw" (some pixels will be drawn more than
once) but since square blocks can be efficiently transferred to the
display the overdraw is acceptable.

Note: It is a difficult decision whether to maintain the convention that
      color is the last argument or to keep compatibility with existing
      line drawing tests. This patch opts for the former and fixes up
      all uses within the existing codebase.

Signed-off-by: Daniel Thompson <daniel@redfelineninja.org.uk>
This commit is contained in:
Daniel Thompson 2020-12-27 08:47:05 +00:00
parent 8a14faa668
commit 8c03ddbb7a
2 changed files with 16 additions and 9 deletions

View file

@ -183,10 +183,10 @@ class TestApp():
t = machine.Timer(id=1, period=8000000)
t.start()
for x, y in points:
draw.line(120, 120, 120+x, 120+y, 0xfbc0)
draw.line(120, 120, 120+y, 120-x, 0x07c0)
draw.line(120, 120, 120-x, 120-y, 0x6b3f)
draw.line(120, 120, 120-y, 120+x, 0xffe0)
draw.line(120, 120, 120+x, 120+y, 4, 0xfb00) # red
draw.line(120, 120, 120+y, 120-x, 3, 0x07c0) # green
draw.line(120, 120, 120-x, 120-y, 5, 0x6b3f) # blue
draw.line(120, 120, 120-y, 120+x, 2, 0xffe0) # yellow
elapsed = t.time()
t.stop()
del t

View file

@ -356,7 +356,7 @@ class Draw565(object):
return chunks
def line(self, x0, y0, x1, y1, color=None):
def line(self, x0, y0, x1, y1, width=1, color=None):
"""Draw a line between points (x0, y0) and (x1, y1).
Example:
@ -370,14 +370,21 @@ class Draw565(object):
:param y0: Y coordinate of the start of the line
:param x1: X coordinate of the end of the line
:param y1: Y coordinate of the end of the line
:param width: Width of the line in pixels
:param color: Colour to draw line, defaults to the foreground colour
"""
if color is None:
color = self._bgfg & 0xffff
px = bytes(((color >> 8) & 0xFF, color & 0xFF))
px = bytes(((color >> 8) & 0xFF, color & 0xFF)) * (width * width)
write_data = self._display.write_data
set_window = self._display.set_window
dw = (width - 1) // 2
x0 -= dw
y0 -= dw
x1 -= dw
y1 -= dw
dx = abs(x1 - x0)
sx = 1 if x0 < x1 else -1
dy = -abs(y1 - y0)
@ -387,12 +394,12 @@ class Draw565(object):
if x1 < x0 or y1 < y0:
x0, x1 = x1, x0
y0, y1 = y1, y0
w = 1 if dx == 0 else dx
h = 1 if dy == 0 else -dy
w = width if dx == 0 else dx
h = width if dy == 0 else -dy
self.fill(color, x0, y0, w, h)
return
while True:
set_window(x0, y0, 1, 1)
set_window(x0, y0, width, width)
write_data(px)
if x0 == x1 and y0 == y1:
break