diff --git a/displayio/_colorconverter.py b/displayio/_colorconverter.py index bba5316..4f50417 100644 --- a/displayio/_colorconverter.py +++ b/displayio/_colorconverter.py @@ -193,7 +193,7 @@ def _convert( and self._cached_colorspace == colorspace and self._cached_input_pixel == input_pixel.pixel ): - output_color = self._cached_output_color + output_color.pixel = self._cached_output_color return rgb888_pixel = input_pixel diff --git a/displayio/_display.py b/displayio/_display.py index 8551f8c..9572a81 100644 --- a/displayio/_display.py +++ b/displayio/_display.py @@ -401,8 +401,8 @@ def _refresh_area(self, area) -> bool: 8 // self._core.colorspace.depth ) - buffer = memoryview(bytearray([0] * (buffer_size * 4))) - mask = memoryview(bytearray([0] * mask_length)) + buffer = memoryview(bytearray([0] * (buffer_size * 4))).cast("I") + mask = memoryview(bytearray([0] * (mask_length * 4))).cast("I") self._core.fill_area(subrectangle, mask, buffer) # Can't acquire display bus; skip the rest of the data. diff --git a/displayio/_ondiskbitmap.py b/displayio/_ondiskbitmap.py index 30598ef..4a638a9 100644 --- a/displayio/_ondiskbitmap.py +++ b/displayio/_ondiskbitmap.py @@ -21,6 +21,7 @@ from typing import Union, BinaryIO from ._helpers import read_word from ._colorconverter import ColorConverter +from ._colorspace import Colorspace from ._palette import Palette __version__ = "0.0.0+auto.0" @@ -110,7 +111,9 @@ def __init__(self, file: Union[str, BinaryIO]) -> None: self._width = read_word(bmp_header, 9) self._height = read_word(bmp_header, 11) - self._colorconverter = ColorConverter() + self._pixel_shader_base = ColorConverter( + input_colorspace=Colorspace.RGB888, dither=False + ) if bits_per_pixel == 16: if header_size >= 56 or self._bitfield_compressed: @@ -126,7 +129,7 @@ def __init__(self, file: Union[str, BinaryIO]) -> None: if number_of_colors == 0: number_of_colors = 1 << bits_per_pixel - palette = Palette(number_of_colors) + palette = Palette(number_of_colors, dither=False) if number_of_colors > 1: palette_size = number_of_colors * 4 @@ -141,11 +144,13 @@ def __init__(self, file: Union[str, BinaryIO]) -> None: raise ValueError("Unable to read color palette data") for i in range(number_of_colors): - palette[i] = palette_data[i] + palette._set_color( + palette_data[i], i + ) # pylint: disable=protected-access else: - palette[0] = 0x000000 - palette[1] = 0xFFFFFF - self._palette = palette + palette._set_color(0x000000, 0) # pylint: disable=protected-access + palette._set_color(0xFFFFFF, 1) # pylint: disable=protected-access + self._pixel_shader_base = palette elif header_size not in (12, 40, 108, 124): raise ValueError( "Only Windows format, uncompressed BMP supported: " @@ -206,22 +211,6 @@ def pixel_shader(self) -> Union[ColorConverter, Palette]: return self._pixel_shader_base - @property - def _colorconverter(self) -> ColorConverter: - return self._pixel_shader_base - - @_colorconverter.setter - def _colorconverter(self, colorconverter: ColorConverter) -> None: - self._pixel_shader_base = colorconverter - - @property - def _palette(self) -> Palette: - return self._pixel_shader_base - - @_palette.setter - def _palette(self, palette: Palette) -> None: - self._pixel_shader_base = palette - def _get_pixel(self, x: int, y: int) -> int: if not (0 <= x < self.width and 0 <= y < self.height): return 0 diff --git a/displayio/_palette.py b/displayio/_palette.py index 81f3bee..6db2402 100644 --- a/displayio/_palette.py +++ b/displayio/_palette.py @@ -44,12 +44,10 @@ def __init__(self, color_count: int, *, dither: bool = False): self._colors = [] for _ in range(color_count): - self._colors.append(self._make_color(0)) + self._colors.append(ColorStruct()) @staticmethod - def _make_color(value, transparent=False): - color = ColorStruct(transparent=transparent) - + def _color_to_int(value): if isinstance(value, (tuple, list, bytes, bytearray)): value = (value[0] & 0xFF) << 16 | (value[1] & 0xFF) << 8 | value[2] & 0xFF elif isinstance(value, int): @@ -57,9 +55,7 @@ def _make_color(value, transparent=False): raise ValueError("Color must be between 0x000000 and 0xFFFFFF") else: raise TypeError("Color buffer must be a buffer, tuple, list, or int") - color.rgb888 = value - - return color + return value def __len__(self) -> int: """Returns the number of colors in a Palette""" @@ -77,10 +73,13 @@ def __setitem__( (to represent an RGB value). Value can be an int, bytes (3 bytes (RGB) or 4 bytes (RGB + pad byte)), bytearray, or a tuple or list of 3 integers. """ - if self._colors[index].rgb888 == value: + self._set_color(index, self._color_to_int(value)) + + def _set_color(self, palette_index: int, color: int): + if self._colors[palette_index].rgb888 == color: return - self._colors[index] = self._make_color(value) - self._colors[index].cached_colorspace = None + self._colors[palette_index].rgb888 = color + self._colors[palette_index].cached_colorspace = None self._needs_refresh = True def __getitem__(self, index: int) -> Optional[int]: diff --git a/displayio/_structs.py b/displayio/_structs.py index 3603295..4c41c00 100644 --- a/displayio/_structs.py +++ b/displayio/_structs.py @@ -88,14 +88,5 @@ class ColorStruct: cached_colorspace_grayscale: bool = False transparent: bool = False - def rgba(self) -> tuple[int, int, int, int]: - """Return the color as a tuple of red, green, blue, alpha""" - return ( - self.rgb888 >> 16, - (self.rgb888 >> 8) & 0xFF, - self.rgb888 & 0xFF, - 0 if self.transparent else 0xFF, - ) - null_transform = TransformStruct() # Use defaults diff --git a/displayio/_tilegrid.py b/displayio/_tilegrid.py index 5abfad4..a87860e 100644 --- a/displayio/_tilegrid.py +++ b/displayio/_tilegrid.py @@ -363,19 +363,18 @@ def _fill_area( if not output_pixel.opaque: full_coverage = False else: - mask[offset // 8] |= 1 << (offset % 8) - # print("Mask", mask) + mask[offset // 32] |= 1 << (offset % 32) if colorspace.depth == 16: struct.pack_into( "H", - buffer, + buffer.cast("B"), offset * 2, output_pixel.pixel, ) elif colorspace.depth == 32: struct.pack_into( "I", - buffer, + buffer.cast("B"), offset * 4, output_pixel.pixel, )