]> Repositories - hackapet/Adafruit_Blinka_Displayio.git/blobdiff - displayio/_tilegrid.py
Merge pull request #136 from FoamyGuy/8.x_compatibility
[hackapet/Adafruit_Blinka_Displayio.git] / displayio / _tilegrid.py
index 91b32326c6244f117cc5f30e2fd914531b339e56..9b8d293e05f7e09f2a2ad9979b17a8e81f570913 100644 (file)
@@ -23,7 +23,6 @@ from circuitpython_typing import WriteableBuffer
 from ._bitmap import Bitmap
 from ._colorconverter import ColorConverter
 from ._ondiskbitmap import OnDiskBitmap
-from ._shape import Shape
 from ._palette import Palette
 from ._structs import (
     InputPixelStruct,
@@ -47,7 +46,7 @@ class TileGrid:
 
     def __init__(
         self,
-        bitmap: Union[Bitmap, OnDiskBitmap, Shape],
+        bitmap: Union[Bitmap, OnDiskBitmap],
         *,
         pixel_shader: Union[ColorConverter, Palette],
         width: int = 1,
@@ -64,7 +63,7 @@ class TileGrid:
 
         tile_width and tile_height match the height of the bitmap by default.
         """
-        if not isinstance(bitmap, (Bitmap, OnDiskBitmap, Shape)):
+        if not isinstance(bitmap, (Bitmap, OnDiskBitmap)):
             raise ValueError("Unsupported Bitmap type")
         self._bitmap = bitmap
         bitmap_width = bitmap.width
@@ -244,10 +243,12 @@ class TileGrid:
 
         if self._hidden_tilegrid or self._hidden_by_parent:
             return False
-
         overlap = Area()  # area, current_area, overlap
         if not area.compute_overlap(self._current_area, overlap):
             return False
+        # else:
+        #    print("Checking", area.x1, area.y1, area.x2, area.y2)
+        #    print("Overlap", overlap.x1, overlap.y1, overlap.x2, overlap.y2)
 
         if self._bitmap.width <= 0 or self._bitmap.height <= 0:
             return False
@@ -339,7 +340,7 @@ class TileGrid:
 
                 # We always want to read bitmap pixels by row first and then transpose into
                 # the destination buffer because most bitmaps are row associated.
-                if isinstance(self._bitmap, (Bitmap, Shape, OnDiskBitmap)):
+                if isinstance(self._bitmap, (Bitmap, OnDiskBitmap)):
                     input_pixel.pixel = (
                         self._bitmap._get_pixel(  # pylint: disable=protected-access
                             input_pixel.tile_x, input_pixel.tile_y
@@ -365,19 +366,19 @@ class TileGrid:
                     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,
                         )
                     elif colorspace.depth == 8:
-                        buffer[offset] = output_pixel.pixel & 0xFF
+                        buffer.cast("B")[offset] = output_pixel.pixel & 0xFF
                     elif colorspace.depth < 8:
                         # Reorder the offsets to pack multiple rows into
                         # a byte (meaning they share a column).
@@ -389,14 +390,17 @@ class TileGrid:
                             # even if we multiply it back out
                             offset = (
                                 col * pixels_per_byte
-                                + (row // pixels_per_byte) * width
+                                + (row // pixels_per_byte) * pixels_per_byte * width
                                 + (row % pixels_per_byte)
                             )
                         shift = (offset % pixels_per_byte) * colorspace.depth
                         if colorspace.reverse_pixels_in_byte:
                             # Reverse the shift by subtracting it from the leftmost shift
                             shift = (pixels_per_byte - 1) * colorspace.depth - shift
-                        buffer[offset // pixels_per_byte] |= output_pixel.pixel << shift
+                        buffer.cast("B")[offset // pixels_per_byte] |= (
+                            output_pixel.pixel << shift
+                        )
+
         return full_coverage
 
     def _finish_refresh(self):
@@ -412,7 +416,7 @@ class TileGrid:
         self._partial_change = False
         if isinstance(self._pixel_shader, (Palette, ColorConverter)):
             self._pixel_shader._finish_refresh()  # pylint: disable=protected-access
-        if isinstance(self._bitmap, (Bitmap, Shape)):
+        if isinstance(self._bitmap, Bitmap):
             self._bitmap._finish_refresh()  # pylint: disable=protected-access
 
     def _get_refresh_areas(self, areas: list[Area]) -> None:
@@ -440,7 +444,7 @@ class TileGrid:
         if isinstance(self._bitmap, Bitmap):
             self._bitmap._get_refresh_areas(areas)  # pylint: disable=protected-access
             refresh_area = areas[-1] if areas else None
-            if tail != refresh_area:
+            if refresh_area != tail:
                 # Special case a TileGrid that shows a full bitmap and use its
                 # dirty area. Copy it to ours so we can transform it.
                 if self._tiles_in_bitmap == 1:
@@ -448,12 +452,6 @@ class TileGrid:
                     self._partial_change = True
                 else:
                     self._full_change = True
-        elif isinstance(self._bitmap, Shape):
-            self._bitmap._get_refresh_areas(areas)  # pylint: disable=protected-access
-            refresh_area = areas[-1] if areas else None
-            if refresh_area != tail:
-                refresh_area.copy_into(self._dirty_area)
-                self._partial_change = True
 
         self._full_change = self._full_change or (
             isinstance(self._pixel_shader, (Palette, ColorConverter))
@@ -529,6 +527,29 @@ class TileGrid:
         )
         self._full_change = True
 
+    def _set_tile(self, x: int, y: int, tile_index: int) -> None:
+        self._tiles[y * self._width_in_tiles + x] = tile_index
+        temp_area = Area()
+        if not self._partial_change:
+            tile_area = self._dirty_area
+        else:
+            tile_area = temp_area
+        top_x = (x - self._top_left_x) % self._width_in_tiles
+        if top_x < 0:
+            top_x += self._width_in_tiles
+        tile_area.x1 = top_x * self._tile_width
+        tile_area.x2 = tile_area.x1 + self._tile_width
+        top_y = (y - self._top_left_y) % self._height_in_tiles
+        if top_y < 0:
+            top_y += self._height_in_tiles
+        tile_area.y1 = top_y * self._tile_height
+        tile_area.y2 = tile_area.y1 + self._tile_height
+
+        if self._partial_change:
+            self._dirty_area.union(temp_area, self._dirty_area)
+
+        self._partial_change = True
+
     def _set_top_left(self, x: int, y: int) -> None:
         self._top_left_x = x
         self._top_left_y = y
@@ -641,19 +662,17 @@ class TileGrid:
         self._full_change = True
 
     @property
-    def bitmap(self) -> Union[Bitmap, OnDiskBitmap, Shape]:
-        """The Bitmap, OnDiskBitmap, or Shape that is assigned to this TileGrid"""
+    def bitmap(self) -> Union[Bitmap, OnDiskBitmap]:
+        """The Bitmap or OnDiskBitmap that is assigned to this TileGrid"""
         return self._bitmap
 
     @bitmap.setter
-    def bitmap(self, new_bitmap: Union[Bitmap, OnDiskBitmap, Shape]) -> None:
-        if (
-            not isinstance(new_bitmap, Bitmap)
-            and not isinstance(new_bitmap, OnDiskBitmap)
-            and not isinstance(new_bitmap, Shape)
+    def bitmap(self, new_bitmap: Union[Bitmap, OnDiskBitmap]) -> None:
+        if not isinstance(new_bitmap, Bitmap) and not isinstance(
+            new_bitmap, OnDiskBitmap
         ):
             raise TypeError(
-                "Unsupported Type: new_bitmap must be Bitmap, OnDiskBitmap, or Shape"
+                "Unsupported Type: new_bitmap must be Bitmap or OnDiskBitmap"
             )
 
         if (
@@ -679,23 +698,23 @@ class TileGrid:
             or index >= len(self._tiles)
         ):
             raise ValueError("Tile index out of bounds")
-        return index
+        return x, y
 
     def __getitem__(self, index: Union[Tuple[int, int], int]) -> int:
         """Returns the tile index at the given index. The index can either be
         an x,y tuple or an int equal to ``y * width + x``'.
         """
-        index = self._extract_and_check_index(index)
-        return self._tiles[index]
+        x, y = self._extract_and_check_index(index)
+        return self._tiles[y * self._width_in_tiles + x]
 
     def __setitem__(self, index: Union[Tuple[int, int], int], value: int) -> None:
         """Sets the tile index at the given index. The index can either be
         an x,y tuple or an int equal to ``y * width + x``.
         """
-        index = self._extract_and_check_index(index)
+        x, y = self._extract_and_check_index(index)
         if not 0 <= value <= 255:
             raise ValueError("Tile value out of bounds")
-        self._tiles[index] = value
+        self._set_tile(x, y, value)
 
     @property
     def width(self) -> int: