1 from displayio import Bitmap
2 import circuitpython_typing
4 def fill_region(dest_bitmap: Bitmap, x1: int, y1: int, x2: int, y2: int, value: int):
5 for y in range(y1, y2):
6 for x in range(x1, x2):
7 dest_bitmap[x,y] = value
9 def draw_line(dest_bitmap: Bitmap, x1: int, y1: int, x2: int, y2: int, value: int):
11 sx = 1 if x1 < x2 else -1
13 sy = 1 if y1 < y2 else -1
17 dest_bitmap[x1, y1] = value
18 if x1 == x2 and y1 == y2:
28 def draw_circle(dest_bitmap: Bitmap, x: int, y: int, radius: int, value: int):
29 x = max(0, min(x, dest_bitmap.width - 1))
30 y = max(0, min(y, dest_bitmap.height - 1))
36 # Bresenham's circle algorithm
38 dest_bitmap[xb + x, yb + y] = value
39 dest_bitmap[-xb + x, -yb + y] = value
40 dest_bitmap[-xb + x, yb + y] = value
41 dest_bitmap[xb + x, -yb + y] = value
42 dest_bitmap[yb + x, xb + y] = value
43 dest_bitmap[-yb + x, xb + y] = value
44 dest_bitmap[-yb + x, -xb + y] = value
45 dest_bitmap[yb + x, -xb + y] = value
50 d = d + 4 * (xb - yb) + 10
55 def draw_polygon(dest_bitmap: Bitmap,
56 xs: circuitpython_typing.ReadableBuffer,
57 ys: circuitpython_typing.ReadableBuffer,
58 value: int, close: bool | None = True):
60 if len(xs) != len(ys):
61 raise ValueError("Length of xs and ys must be equal.")
63 for i in range(len(xs)-1):
64 cur_point = (xs[i], ys[i])
65 next_point = (xs[i+1], ys[i+1])
66 print(f"cur: {cur_point}, next: {next_point}")
67 draw_line(dest_bitmap=dest_bitmap,
68 x1=cur_point[0], y1=cur_point[1],
69 x2=next_point[0], y2=next_point[1],
73 print(f"close: {(xs[0], ys[0])} - {(xs[-1], ys[-1])}")
74 draw_line(dest_bitmap=dest_bitmap,
79 def blit(dest_bitmap: Bitmap, source_bitmap: Bitmap,
81 x1: int = 0, y1: int = 0,
82 x2: int | None = None, y2: int | None = None,
83 skip_source_index: int | None = None,
84 skip_dest_index: int | None = None):
86 """Inserts the source_bitmap region defined by rectangular boundaries"""
87 # pylint: disable=invalid-name
89 x2 = source_bitmap.width
91 y2 = source_bitmap.height
93 # Rearrange so that x1 < x2 and y1 < y2
99 # Ensure that x2 and y2 are within source bitmap size
100 x2 = min(x2, source_bitmap.width)
101 y2 = min(y2, source_bitmap.height)
103 for y_count in range(y2 - y1):
104 for x_count in range(x2 - x1):
105 x_placement = x + x_count
106 y_placement = y + y_count
108 if (dest_bitmap.width > x_placement >= 0) and (
109 dest_bitmap.height > y_placement >= 0
110 ): # ensure placement is within target bitmap
111 # get the palette index from the source bitmap
112 this_pixel_color = source_bitmap[
113 y1 + (y_count * source_bitmap.width) + x1 + x_count
116 if (skip_source_index is None) or (this_pixel_color != skip_source_index):
117 if (skip_dest_index is None) or (dest_bitmap[y_placement * dest_bitmap.width + x_placement] != skip_dest_index):
118 dest_bitmap[ # Direct index into a bitmap array is speedier than [x,y] tuple
119 y_placement * dest_bitmap.width + x_placement
121 elif y_placement > dest_bitmap.height: