|
25 | 25 |
|
26 | 26 | CircuitPython pure-python framebuf module, based on the micropython framebuf module.
|
27 | 27 |
|
28 |
| -* Author(s): Kattni Rembor, Tony DiCola, original file created by Damien P. George |
| 28 | +* Author(s): Melissa LeBlanc-Williams, Kattni Rembor, Tony DiCola, original file |
| 29 | + created by Damien P. George |
29 | 30 |
|
30 | 31 | Implementation Notes
|
31 | 32 | --------------------
|
|
52 | 53 | RGB565 = 1 # 16-bit color displays
|
53 | 54 | GS4_HMSB = 2 # Unimplemented!
|
54 | 55 | MHMSB = 3 # Single bit displays like the Sharp Memory
|
| 56 | +RGB888 = 4 # Neopixels and Dotstars |
55 | 57 |
|
56 | 58 |
|
57 | 59 | class MHMSBFormat:
|
@@ -142,6 +144,46 @@ def fill_rect(framebuf, x, y, width, height, color):
|
142 | 144 | height -= 1
|
143 | 145 |
|
144 | 146 |
|
| 147 | +class RGB888Format: |
| 148 | + """RGB888Format""" |
| 149 | + |
| 150 | + @staticmethod |
| 151 | + def set_pixel(framebuf, x, y, color): |
| 152 | + """Set a given pixel to a color.""" |
| 153 | + index = (y * framebuf.stride + x) * 3 |
| 154 | + framebuf.buf[index : index + 3] = bytes( |
| 155 | + ((color >> 16) & 255, (color >> 8) & 255, color & 255) |
| 156 | + ) |
| 157 | + |
| 158 | + @staticmethod |
| 159 | + def get_pixel(framebuf, x, y): |
| 160 | + """Get the color of a given pixel""" |
| 161 | + index = (y * framebuf.stride + x) * 3 |
| 162 | + return ( |
| 163 | + (framebuf.buf[index] << 16) |
| 164 | + | (framebuf.buf[index + 1] << 8) |
| 165 | + | framebuf.buf[index + 2] |
| 166 | + ) |
| 167 | + |
| 168 | + @staticmethod |
| 169 | + def fill(framebuf, color): |
| 170 | + """completely fill/clear the buffer with a color""" |
| 171 | + fill = (color >> 16) & 255, (color >> 8) & 255, color & 255 |
| 172 | + for i in range(0, len(framebuf.buf), 3): |
| 173 | + framebuf.buf[i : i + 3] = bytes(fill) |
| 174 | + |
| 175 | + @staticmethod |
| 176 | + def fill_rect(framebuf, x, y, width, height, color): |
| 177 | + """Draw a rectangle at the given location, size and color. The ``fill_rect`` method draws |
| 178 | + both the outline and interior.""" |
| 179 | + # pylint: disable=too-many-arguments |
| 180 | + fill = (color >> 16) & 255, (color >> 8) & 255, color & 255 |
| 181 | + for _x in range(x, x + width): |
| 182 | + for _y in range(y, y + height): |
| 183 | + index = (_y * framebuf.stride + _x) * 3 |
| 184 | + framebuf.buf[index : index + 3] = bytes(fill) |
| 185 | + |
| 186 | + |
145 | 187 | class FrameBuffer:
|
146 | 188 | """FrameBuffer object.
|
147 | 189 |
|
@@ -174,6 +216,8 @@ def __init__(self, buf, width, height, buf_format=MVLSB, stride=None):
|
174 | 216 | self.format = MVLSBFormat()
|
175 | 217 | elif buf_format == MHMSB:
|
176 | 218 | self.format = MHMSBFormat()
|
| 219 | + elif buf_format == RGB888: |
| 220 | + self.format = RGB888Format() |
177 | 221 | else:
|
178 | 222 | raise ValueError("invalid format")
|
179 | 223 | self._rotation = 0
|
@@ -360,12 +404,18 @@ def text(self, string, x, y, color, *, font_name="font5x8.bin", size=1):
|
360 | 404 | if not self._font or self._font.font_name != font_name:
|
361 | 405 | # load the font!
|
362 | 406 | self._font = BitmapFont(font_name)
|
363 |
| - w = self._font.font_width |
| 407 | + width = self._font.font_width |
| 408 | + height = self._font.font_height |
364 | 409 | for i, char in enumerate(chunk):
|
365 |
| - self._font.draw_char( |
366 |
| - char, x + (i * (w + 1)) * size, y, self, color, size=size |
367 |
| - ) |
368 |
| - y += self._font.font_height * size |
| 410 | + char_x = x + (i * (width + 1)) * size |
| 411 | + if ( |
| 412 | + char_x + (width * size) > 0 |
| 413 | + and char_x < self.width |
| 414 | + and y + (height * size) > 0 |
| 415 | + and y < self.height |
| 416 | + ): |
| 417 | + self._font.draw_char(char, char_x, y, self, color, size=size) |
| 418 | + y += height * size |
369 | 419 |
|
370 | 420 | # pylint: enable=too-many-arguments
|
371 | 421 |
|
|
0 commit comments