refactor displayio set_pixel for use in bitmap_tools
This commit is contained in:
parent
a4133c4545
commit
0c012da080
|
@ -105,17 +105,92 @@ uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *self, int16_t
|
||||||
return 0;
|
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,
|
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) {
|
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"
|
// Copy region of "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
|
|
||||||
// If skip_value is encountered in the source bitmap, it will not be copied.
|
// If skip_value is encountered in the source bitmap, it will not be copied.
|
||||||
// If skip_value is `None`, then all pixels are 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) {
|
if (self->read_only) {
|
||||||
mp_raise_RuntimeError(translate("Read-only object"));
|
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 x_reverse = false;
|
||||||
bool y_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) ) {
|
if ((yd_index >= 0) && (yd_index < self->height) ) {
|
||||||
uint32_t value = common_hal_displayio_bitmap_get_pixel(source, xs_index, ys_index);
|
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
|
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) {
|
if (self->read_only) {
|
||||||
mp_raise_RuntimeError(translate("Read-only object"));
|
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
|
// update the dirty region
|
||||||
int32_t row_start = y * self->stride;
|
displayio_bitmap_set_dirty_area(self, x, y, x+1, y+1);
|
||||||
uint32_t bytes_per_value = self->bits_per_value / 8;
|
|
||||||
if (bytes_per_value < 1) {
|
// write the pixel
|
||||||
uint32_t bit_position = (sizeof(size_t) * 8 - ((x & self->x_mask) + 1) * self->bits_per_value);
|
displayio_bitmap_write_pixel(self, x, y, 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
displayio_area_t* displayio_bitmap_get_refresh_areas(displayio_bitmap_t *self, displayio_area_t* tail) {
|
displayio_area_t* displayio_bitmap_get_refresh_areas(displayio_bitmap_t *self, displayio_area_t* tail) {
|
||||||
|
|
Loading…
Reference in New Issue