diff --git a/adafruit_framebuf.py b/adafruit_framebuf.py index 5afd8ef..8d0c63a 100755 --- a/adafruit_framebuf.py +++ b/adafruit_framebuf.py @@ -25,7 +25,8 @@ CircuitPython pure-python framebuf module, based on the micropython framebuf module. -* Author(s): Kattni Rembor, Tony DiCola, original file created by Damien P. George +* Author(s): Melissa LeBlanc-Williams, Kattni Rembor, Tony DiCola, original file + created by Damien P. George Implementation Notes -------------------- @@ -52,6 +53,7 @@ RGB565 = 1 # 16-bit color displays GS4_HMSB = 2 # Unimplemented! MHMSB = 3 # Single bit displays like the Sharp Memory +RGB888 = 4 # Neopixels and Dotstars class MHMSBFormat: @@ -142,6 +144,46 @@ def fill_rect(framebuf, x, y, width, height, color): height -= 1 +class RGB888Format: + """RGB888Format""" + + @staticmethod + def set_pixel(framebuf, x, y, color): + """Set a given pixel to a color.""" + index = (y * framebuf.stride + x) * 3 + framebuf.buf[index : index + 3] = bytes( + ((color >> 16) & 255, (color >> 8) & 255, color & 255) + ) + + @staticmethod + def get_pixel(framebuf, x, y): + """Get the color of a given pixel""" + index = (y * framebuf.stride + x) * 3 + return ( + (framebuf.buf[index] << 16) + | (framebuf.buf[index + 1] << 8) + | framebuf.buf[index + 2] + ) + + @staticmethod + def fill(framebuf, color): + """completely fill/clear the buffer with a color""" + fill = (color >> 16) & 255, (color >> 8) & 255, color & 255 + for i in range(0, len(framebuf.buf), 3): + framebuf.buf[i : i + 3] = bytes(fill) + + @staticmethod + def fill_rect(framebuf, x, y, width, height, color): + """Draw a rectangle at the given location, size and color. The ``fill_rect`` method draws + both the outline and interior.""" + # pylint: disable=too-many-arguments + fill = (color >> 16) & 255, (color >> 8) & 255, color & 255 + for _x in range(x, x + width): + for _y in range(y, y + height): + index = (_y * framebuf.stride + _x) * 3 + framebuf.buf[index : index + 3] = bytes(fill) + + class FrameBuffer: """FrameBuffer object. @@ -174,6 +216,8 @@ def __init__(self, buf, width, height, buf_format=MVLSB, stride=None): self.format = MVLSBFormat() elif buf_format == MHMSB: self.format = MHMSBFormat() + elif buf_format == RGB888: + self.format = RGB888Format() else: raise ValueError("invalid format") self._rotation = 0 @@ -360,12 +404,18 @@ def text(self, string, x, y, color, *, font_name="font5x8.bin", size=1): if not self._font or self._font.font_name != font_name: # load the font! self._font = BitmapFont(font_name) - w = self._font.font_width + width = self._font.font_width + height = self._font.font_height for i, char in enumerate(chunk): - self._font.draw_char( - char, x + (i * (w + 1)) * size, y, self, color, size=size - ) - y += self._font.font_height * size + char_x = x + (i * (width + 1)) * size + if ( + char_x + (width * size) > 0 + and char_x < self.width + and y + (height * size) > 0 + and y < self.height + ): + self._font.draw_char(char, char_x, y, self, color, size=size) + y += height * size # pylint: enable=too-many-arguments