diff options
| author | DavePutz <dwputz@gmail.com> | 2021-03-10 13:55:09 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-10 13:55:09 -0600 |
| commit | ef0ce0df72882555bf6e65580dbab1f15f787f02 (patch) | |
| tree | dcb31aa33239e68e1f530b529f0cf0be8642d9b9 /shared-module/displayio | |
| parent | afa508cb47a601f68f8c969400d349d60b80f6d5 (diff) | |
| parent | be9e045ee3562e4fff0f982a4bf53654da8107b6 (diff) | |
Merge pull request #43 from adafruit/main
Update from adafruit main
Diffstat (limited to 'shared-module/displayio')
| -rw-r--r-- | shared-module/displayio/Bitmap.c | 125 | ||||
| -rw-r--r-- | shared-module/displayio/Group.c | 2 | ||||
| -rw-r--r-- | shared-module/displayio/TileGrid.c | 39 | ||||
| -rw-r--r-- | shared-module/displayio/__init__.c | 14 | ||||
| -rw-r--r-- | shared-module/displayio/area.h | 2 |
5 files changed, 128 insertions, 54 deletions
diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index c9ea83428..1831ac697 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -105,17 +105,92 @@ uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *self, int16_t return 0; } +void displayio_bitmap_set_dirty_area(displayio_bitmap_t *self, int16_t x1, int16_t y1, int16_t x2, int16_t y2) { + // Update the bitmap's dirty region with the rectangle bounded by (x1,y1) and (x2, y2) + + // Arrange x1 < x2, y1 < y2 + if (x1 > x2) { + int16_t temp = x1; + x1 = x2; + x2 = temp; + } + if (y1 > y2) { + int16_t temp = y1; + y1 = y2; + y2 = temp; + } + + // Update the dirty area. + if (self->dirty_area.x1 == self->dirty_area.x2) { + self->dirty_area.x1 = x1; + self->dirty_area.x2 = x2; + self->dirty_area.y1 = y1; + self->dirty_area.y2 = y2; + } else { + if (x1 < self->dirty_area.x1) { + self->dirty_area.x1 = x1; + } + if (x2 > self->dirty_area.x2) { + self->dirty_area.x2 = x2; + } + if (y1 < self->dirty_area.y1) { + self->dirty_area.y1 = y1; + } + if (y2 > self->dirty_area.y2) { + self->dirty_area.y2 = y2; + } + } +} + +void displayio_bitmap_write_pixel(displayio_bitmap_t *self, int16_t x, int16_t y, uint32_t value) { + // Writes the color index value into a pixel position + // Must update the dirty area separately + + // Update one pixel of data + int32_t row_start = y * self->stride; + uint32_t bytes_per_value = self->bits_per_value / 8; + if (bytes_per_value < 1) { + uint32_t bit_position = (sizeof(size_t) * 8 - ((x & self->x_mask) + 1) * self->bits_per_value); + uint32_t index = row_start + (x >> self->x_shift); + uint32_t word = self->data[index]; + word &= ~(self->bitmask << bit_position); + word |= (value & self->bitmask) << bit_position; + self->data[index] = word; + } else { + size_t* row = self->data + row_start; + if (bytes_per_value == 1) { + ((uint8_t*) row)[x] = value; + } else if (bytes_per_value == 2) { + ((uint16_t*) row)[x] = value; + } else if (bytes_per_value == 4) { + ((uint32_t*) row)[x] = value; + } + } +} + void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16_t y, displayio_bitmap_t *source, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint32_t skip_index, bool skip_index_none) { - // Copy complete "source" bitmap into "self" bitmap at location x,y in the "self" - // Add a boolean to determine if all values are copied, or only if non-zero + // Copy region of "source" bitmap into "self" bitmap at location x,y in the "self" // If skip_value is encountered in the source bitmap, it will not be copied. // If skip_value is `None`, then all pixels are copied. + // This function assumes input checks were performed for pixel index entries. if (self->read_only) { mp_raise_RuntimeError(translate("Read-only object")); } + // Update the dirty area + int16_t dirty_x_max = (x + (x2-x1)); + if (dirty_x_max > self->width) { + dirty_x_max = self->width; + } + int16_t dirty_y_max = y + (y2-y1); + if (dirty_y_max > self->height) { + dirty_y_max = self->height; + } + + displayio_bitmap_set_dirty_area(self, x, y, dirty_x_max, dirty_y_max); + bool x_reverse = false; bool y_reverse = false; @@ -142,7 +217,7 @@ void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16 if ((yd_index >= 0) && (yd_index < self->height) ) { uint32_t value = common_hal_displayio_bitmap_get_pixel(source, xs_index, ys_index); if ( (skip_index_none) || (value != skip_index) ) { // write if skip_value_none is True - common_hal_displayio_bitmap_set_pixel(self, xd_index, yd_index, value); + displayio_bitmap_write_pixel(self, xd_index, yd_index, value); } } } @@ -154,45 +229,13 @@ void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x, if (self->read_only) { mp_raise_RuntimeError(translate("Read-only object")); } - // Update the dirty area. - if (self->dirty_area.x1 == self->dirty_area.x2) { - self->dirty_area.x1 = x; - self->dirty_area.x2 = x + 1; - self->dirty_area.y1 = y; - self->dirty_area.y2 = y + 1; - } else { - if (x < self->dirty_area.x1) { - self->dirty_area.x1 = x; - } else if (x >= self->dirty_area.x2) { - self->dirty_area.x2 = x + 1; - } - if (y < self->dirty_area.y1) { - self->dirty_area.y1 = y; - } else if (y >= self->dirty_area.y2) { - self->dirty_area.y2 = y + 1; - } - } - // Update our data - int32_t row_start = y * self->stride; - uint32_t bytes_per_value = self->bits_per_value / 8; - if (bytes_per_value < 1) { - uint32_t bit_position = (sizeof(size_t) * 8 - ((x & self->x_mask) + 1) * self->bits_per_value); - uint32_t index = row_start + (x >> self->x_shift); - uint32_t word = self->data[index]; - word &= ~(self->bitmask << bit_position); - word |= (value & self->bitmask) << bit_position; - self->data[index] = word; - } else { - size_t* row = self->data + row_start; - if (bytes_per_value == 1) { - ((uint8_t*) row)[x] = value; - } else if (bytes_per_value == 2) { - ((uint16_t*) row)[x] = value; - } else if (bytes_per_value == 4) { - ((uint32_t*) row)[x] = value; - } - } + // update the dirty region + displayio_bitmap_set_dirty_area(self, x, y, x+1, y+1); + + // write the pixel + displayio_bitmap_write_pixel(self, x, y, value); + } displayio_area_t* displayio_bitmap_get_refresh_areas(displayio_bitmap_t *self, displayio_area_t* tail) { diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index 42efeb18c..a36acc1c3 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -340,7 +340,7 @@ mp_obj_t common_hal_displayio_group_get(displayio_group_t* self, size_t index) { void common_hal_displayio_group_set(displayio_group_t* self, size_t index, mp_obj_t layer) { _add_layer(self, layer); _remove_layer(self, index); - mp_obj_list_store(self, MP_OBJ_NEW_SMALL_INT(index), layer); + mp_obj_list_store(self->members, MP_OBJ_NEW_SMALL_INT(index), layer); } void displayio_group_construct(displayio_group_t* self, mp_obj_list_t* members, uint32_t scale, mp_int_t x, mp_int_t y) { diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index 19ea10e55..96473d4a8 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -74,6 +74,7 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_ self->flip_x = false; self->flip_y = false; self->transpose_xy = false; + self->absolute_transform = NULL; } @@ -104,23 +105,30 @@ bool displayio_tilegrid_get_previous_area(displayio_tilegrid_t *self, displayio_ } void _update_current_x(displayio_tilegrid_t *self) { - int16_t width; + uint16_t width; if (self->transpose_xy) { width = self->pixel_height; } else { width = self->pixel_width; } - if (self->absolute_transform->transpose_xy) { - self->current_area.y1 = self->absolute_transform->y + self->absolute_transform->dy * self->x; - self->current_area.y2 = self->absolute_transform->y + self->absolute_transform->dy * (self->x + width); + + // If there's no transform, substitute an identity transform so the calculations will work. + const displayio_buffer_transform_t* absolute_transform = + self->absolute_transform == NULL + ? &null_transform + : self->absolute_transform; + + if (absolute_transform->transpose_xy) { + self->current_area.y1 = absolute_transform->y + absolute_transform->dy * self->x; + self->current_area.y2 = absolute_transform->y + absolute_transform->dy * (self->x + width); if (self->current_area.y2 < self->current_area.y1) { int16_t temp = self->current_area.y2; self->current_area.y2 = self->current_area.y1; self->current_area.y1 = temp; } } else { - self->current_area.x1 = self->absolute_transform->x + self->absolute_transform->dx * self->x; - self->current_area.x2 = self->absolute_transform->x + self->absolute_transform->dx * (self->x + width); + self->current_area.x1 = absolute_transform->x + absolute_transform->dx * self->x; + self->current_area.x2 = absolute_transform->x + absolute_transform->dx * (self->x + width); if (self->current_area.x2 < self->current_area.x1) { int16_t temp = self->current_area.x2; self->current_area.x2 = self->current_area.x1; @@ -130,23 +138,30 @@ void _update_current_x(displayio_tilegrid_t *self) { } void _update_current_y(displayio_tilegrid_t *self) { - int16_t height; + uint16_t height; if (self->transpose_xy) { height = self->pixel_width; } else { height = self->pixel_height; } - if (self->absolute_transform->transpose_xy) { - self->current_area.x1 = self->absolute_transform->x + self->absolute_transform->dx * self->y; - self->current_area.x2 = self->absolute_transform->x + self->absolute_transform->dx * (self->y + height); + + // If there's no transform, substitute an identity transform so the calculations will work. + const displayio_buffer_transform_t* absolute_transform = + self->absolute_transform == NULL + ? &null_transform + : self->absolute_transform; + + if (absolute_transform->transpose_xy) { + self->current_area.x1 = absolute_transform->x + absolute_transform->dx * self->y; + self->current_area.x2 = absolute_transform->x + absolute_transform->dx * (self->y + height); if (self->current_area.x2 < self->current_area.x1) { int16_t temp = self->current_area.x2; self->current_area.x2 = self->current_area.x1; self->current_area.x1 = temp; } } else { - self->current_area.y1 = self->absolute_transform->y + self->absolute_transform->dy * self->y; - self->current_area.y2 = self->absolute_transform->y + self->absolute_transform->dy * (self->y + height); + self->current_area.y1 = absolute_transform->y + absolute_transform->dy * self->y; + self->current_area.y2 = absolute_transform->y + absolute_transform->dy * (self->y + height); if (self->current_area.y2 < self->current_area.y1) { int16_t temp = self->current_area.y2; self->current_area.y2 = self->current_area.y1; diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index a9bb3b21b..740af0570 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -26,6 +26,20 @@ primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; +displayio_buffer_transform_t null_transform = { + .x = 0, + .y = 0, + .dx = 1, + .dy = 1, + .scale = 1, + .width = 0, + .height = 0, + .mirror_x = false, + .mirror_y = false, + .transpose_xy = false +}; + + #if CIRCUITPY_RGBMATRIX STATIC bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { diff --git a/shared-module/displayio/area.h b/shared-module/displayio/area.h index ec7c389b4..7ad36883c 100644 --- a/shared-module/displayio/area.h +++ b/shared-module/displayio/area.h @@ -51,6 +51,8 @@ typedef struct { bool transpose_xy; } displayio_buffer_transform_t; +extern displayio_buffer_transform_t null_transform; + void displayio_area_union(const displayio_area_t* a, const displayio_area_t* b, displayio_area_t* u); |
