]> Repositories - hackapet/Adafruit_Blinka_Displayio.git/commitdiff
Merge pull request #116 from makermelissa/main 1.0.1
authorMelissa LeBlanc-Williams <melissa@adafruit.com>
Sat, 30 Sep 2023 05:37:52 +0000 (22:37 -0700)
committerGitHub <noreply@github.com>
Sat, 30 Sep 2023 05:37:52 +0000 (22:37 -0700)
Bug fixes and optimizations

displayio/_colorconverter.py
displayio/_display.py
displayio/_ondiskbitmap.py
displayio/_palette.py
displayio/_structs.py
displayio/_tilegrid.py

index bba5316b31d36165a204e4fe9b3bc6098580851e..4f50417f103056cafca970514ecfe53414a9618a 100644 (file)
@@ -193,7 +193,7 @@ class ColorConverter:
             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
index 8551f8c87fded9cea51a104f207a773995c698ca..9572a8132462e0c10f8987f11a43f31618dbcf6f 100644 (file)
@@ -401,8 +401,8 @@ class Display:
                     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.
index 30598ef185936afe352f6a3ee0deadd4354d3833..4a638a9b6eb6060e1543d10916e8b3b4b63e82ea 100644 (file)
@@ -21,6 +21,7 @@ displayio for Blinka
 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 @@ class OnDiskBitmap:
             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 @@ class OnDiskBitmap:
                 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 @@ class OnDiskBitmap:
                         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 @@ class OnDiskBitmap:
 
         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
index 81f3bee5081e3c315f8866eb62f06a6d236dd084..6db240252b7a77184e88d34d945cb40b399eb1cd 100644 (file)
@@ -44,12 +44,10 @@ class Palette:
 
         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 @@ class Palette:
                 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 @@ class Palette:
         (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]:
index 3603295bbeb4bb0a306a33db810e14f8e27ea352..4c41c0054ed902cc85e4c88ac6a1bc7dbb78955b 100644 (file)
@@ -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
index 5abfad44296ea7441930e5bd0b372f88888cdf4a..a87860eff7f7e8f2eb376fd7285c612243f42867 100644 (file)
@@ -363,19 +363,18 @@ class TileGrid:
                 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,
                         )