]> Repositories - hackapet/Adafruit_Blinka_Displayio.git/blobdiff - displayio/_bitmap.py
adding blit implementation to Bitmap
[hackapet/Adafruit_Blinka_Displayio.git] / displayio / _bitmap.py
index f28e72a15961201994042f92deaaf028b13f71eb..12e20afb48ea07c552d16d53cc1238173a2f1e55 100644 (file)
@@ -19,14 +19,12 @@ displayio for Blinka
 
 from __future__ import annotations
 from typing import Union, Tuple
-from recordclass import recordclass
 from PIL import Image
+from ._structs import RectangleStruct
 
 __version__ = "0.0.0-auto.0"
 __repo__ = "https://github.com/adafruit/Adafruit_Blinka_displayio.git"
 
-Rectangle = recordclass("Rectangle", "x1 y1 x2 y2")
-
 
 class Bitmap:
     """Stores values of a certain size in a 2D array"""
@@ -61,7 +59,7 @@ class Bitmap:
             raise NotImplementedError("Invalid bits per value")
 
         self._image = Image.new("P", (width, height), 0)
-        self._dirty_area = Rectangle(0, 0, width, height)
+        self._dirty_area = RectangleStruct(0, 0, width, height)
 
     def __getitem__(self, index: Union[Tuple[int, int], int]) -> int:
         """
@@ -117,7 +115,7 @@ class Bitmap:
     def fill(self, value: int) -> None:
         """Fills the bitmap with the supplied palette index value."""
         self._image = Image.new("P", (self._bmp_width, self._bmp_height), value)
-        self._dirty_area = Rectangle(0, 0, self._bmp_width, self._bmp_height)
+        self._dirty_area = RectangleStruct(0, 0, self._bmp_width, self._bmp_height)
 
     def blit(
         self,
@@ -133,7 +131,46 @@ class Bitmap:
     ) -> None:
         # pylint: disable=unnecessary-pass, invalid-name
         """Inserts the source_bitmap region defined by rectangular boundaries"""
-        pass
+        if x2 is None:
+            x2 = source_bitmap.width
+        if y2 is None:
+            y2 = source_bitmap.height
+
+        # Rearrange so that x1 < x2 and y1 < y2
+        if x1 > x2:
+            x1, x2 = x2, x1
+        if y1 > y2:
+            y1, y2 = y2, y1
+
+        # Ensure that x2 and y2 are within source bitmap size
+        x2 = min(x2, source_bitmap.width)
+        y2 = min(y2, source_bitmap.height)
+
+        for y_count in range(y2 - y1):
+            for x_count in range(x2 - x1):
+                x_placement = x + x_count
+                y_placement = y + y_count
+
+                if (self.width > x_placement >= 0) and (
+                    self.height > y_placement >= 0
+                ):  # ensure placement is within target bitmap
+
+                    # get the palette index from the source bitmap
+                    this_pixel_color = source_bitmap[
+                        y1
+                        + (
+                            y_count * source_bitmap.width
+                        )  # Direct index into a bitmap array is speedier than [x,y] tuple
+                        + x1
+                        + x_count
+                    ]
+
+                    if (skip_index is None) or (this_pixel_color != skip_index):
+                        self[  # Direct index into a bitmap array is speedier than [x,y] tuple
+                            y_placement * self.width + x_placement
+                        ] = this_pixel_color
+                elif y_placement > self.height:
+                    break
 
     def dirty(self, x1: int = 0, y1: int = 0, x2: int = -1, y2: int = -1) -> None:
         # pylint: disable=unnecessary-pass, invalid-name