__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_Blinka_displayio.git"
-ALIGN_BITS = 8 * struct.calcsize("I")
-
def stride(width: int, bits_per_pixel: int) -> int:
"""Return the number of bytes per row of a bitmap with the given width and bits per pixel."""
row_width = width * bits_per_pixel
- return (row_width + (ALIGN_BITS - 1)) // ALIGN_BITS
+ return (row_width + (31)) // 32
class Bitmap:
the Bitmap.
"""
- if not 1 <= value_count <= 65535:
- raise ValueError("value_count must be in the range of 1-65535")
+ if not 1 <= value_count <= 65536:
+ raise ValueError("value_count must be in the range of 1-65536")
bits = 1
while (value_count - 1) >> bits:
self._x_shift = 0
power_of_two = 1
- while power_of_two < ALIGN_BITS // bits_per_value:
+ while power_of_two < 32 // bits_per_value:
self._x_shift += 1
power_of_two = power_of_two << 1
- self._x_mask = (1 << self._x_shift) - 1 # UUsed as a modulus on the x value
+ self._x_mask = (1 << self._x_shift) - 1 # Used as a modulus on the x value
self._bitmask = (1 << bits_per_value) - 1
self._dirty_area = Area(0, 0, width, height)
if bytes_per_value < 1:
word = self._data[row_start + (x >> self._x_shift)]
return (
- word
- >> (
- struct.calcsize("I") * 8
- - ((x & self._x_mask) + 1) * self._bits_per_value
- )
+ word >> (32 - ((x & self._x_mask) + 1) * self._bits_per_value)
) & self._bitmask
row = memoryview(self._data)[row_start : row_start + self._stride]
if bytes_per_value == 1:
row_start = y * self._stride
bytes_per_value = self._bits_per_value // 8
if bytes_per_value < 1:
- bit_position = (
- struct.calcsize("I") * 8
- - ((x & self._x_mask) + 1) * self._bits_per_value
- )
+ bit_position = 32 - ((x & self._x_mask) + 1) * self._bits_per_value
index = row_start + (x >> self._x_shift)
word = self._data[index]
word &= ~(self._bitmask << bit_position)
elif bytes_per_value == 4:
struct.pack_into("<I", row, x * 4, value)
- def _finish_refresh(self):
- self._dirty_area.x1 = 0
- self._dirty_area.x2 = 0
-
def fill(self, value: int) -> None:
"""Fills the bitmap with the supplied palette index value."""
if self._read_only:
for i in range(self._stride * self._bmp_height):
self._data[i] = word
- def blit(
- self,
- x: int,
- y: int,
- source_bitmap: Bitmap,
- *,
- x1: int,
- y1: int,
- x2: int,
- y2: int,
- skip_index: int,
- ) -> None:
- """Inserts the source_bitmap region defined by rectangular boundaries"""
- # pylint: disable=invalid-name
- 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:
"""Inform displayio of bitmap updates done via the buffer protocol."""
# pylint: disable=invalid-name