diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index cc96babfa0421..2df39bb85f856 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -550,6 +550,7 @@ msgstr "" #: ports/atmel-samd/common-hal/displayio/ParallelBus.c #: ports/esp32s2/common-hal/displayio/ParallelBus.c #: ports/nrf/common-hal/displayio/ParallelBus.c +#: ports/raspberrypi/common-hal/displayio/ParallelBus.c #, c-format msgid "Bus pin %d is already in use" msgstr "" @@ -1635,6 +1636,10 @@ msgstr "" msgid "Odd parity is not supported" msgstr "" +#: shared-module/displayio/OnDiskBitmap.c +msgid "OnDiskBitmap is raw color, not indexed" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "Only 8 or 16 bit mono with " @@ -1729,7 +1734,6 @@ msgid "PWM slice channel A already in use" msgstr "" #: ports/mimxrt10xx/common-hal/displayio/ParallelBus.c -#: ports/raspberrypi/common-hal/displayio/ParallelBus.c #: ports/stm/common-hal/displayio/ParallelBus.c msgid "ParallelBus not yet supported" msgstr "" @@ -3106,6 +3110,14 @@ msgstr "" msgid "index is out of bounds" msgstr "" +#: shared-module/displayio/OnDiskBitmap.c +msgid "index is outside OnDiskBitmap palette size" +msgstr "" + +#: shared-module/displayio/OnDiskBitmap.c +msgid "index is outside of palette size" +msgstr "" + #: extmod/ulab/code/numerical/numerical.c #: ports/esp32s2/common-hal/pulseio/PulseIn.c py/obj.c msgid "index out of range" @@ -3662,10 +3674,14 @@ msgstr "" msgid "palette must be 32 bytes long" msgstr "" -#: shared-bindings/displayio/Palette.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/displayio/Palette.c msgid "palette_index should be an int" msgstr "" +#: shared-bindings/displayio/OnDiskBitmap.c +msgid "palette_index, palette_value should be an int" +msgstr "" + #: py/compile.c msgid "parameter annotation must be an identifier" msgstr "" @@ -3950,6 +3966,10 @@ msgstr "" msgid "syntax error in uctypes descriptor" msgstr "" +#: shared-module/displayio/OnDiskBitmap.c +msgid "this OnDiskBitmap is raw color, not indexed" +msgstr "" + #: shared-bindings/touchio/TouchIn.c msgid "threshold must be in the range 0-65536" msgstr "" diff --git a/shared-bindings/displayio/OnDiskBitmap.c b/shared-bindings/displayio/OnDiskBitmap.c index e41f54edfb5e7..9b64d403b5dce 100644 --- a/shared-bindings/displayio/OnDiskBitmap.c +++ b/shared-bindings/displayio/OnDiskBitmap.c @@ -127,9 +127,57 @@ const mp_obj_property_t displayio_ondiskbitmap_height_obj = { }; +//| def palette_size(self) -> int: +//| """Returns the OnDiskBitmap palette size.""" +//| ... +//| +STATIC mp_obj_t displayio_ondiskbitmap_obj_palette_size(mp_obj_t self_in) { + displayio_ondiskbitmap_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_ondiskbitmap_palette_size(self)); +} + +MP_DEFINE_CONST_FUN_OBJ_1(displayio_ondiskbitmap_palette_size_obj, displayio_ondiskbitmap_obj_palette_size); + +//| def get_palette(self, palette_index: int) -> int: +//| """Get the color value of the palette value at the specified index.""" +//| ... +//| +STATIC mp_obj_t displayio_ondiskbitmap_obj_get_palette(mp_obj_t self_in, mp_obj_t palette_index_obj) { + displayio_ondiskbitmap_t *self = MP_OBJ_TO_PTR(self_in); + mp_int_t palette_index; + if (!mp_obj_get_int_maybe(palette_index_obj, &palette_index)) { + mp_raise_ValueError(translate("palette_index should be an int")); + } + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_ondiskbitmap_get_palette(self, palette_index)); +} + +MP_DEFINE_CONST_FUN_OBJ_2(displayio_ondiskbitmap_get_palette_obj, displayio_ondiskbitmap_obj_get_palette); + +//| def set_palette(self, palette_index: int, palette_value: int) -> None: +//| """Set the color value of the palette at the specified index.""" +//| ... +//| +STATIC mp_obj_t displayio_ondiskbitmap_obj_set_palette(mp_obj_t self_in, mp_obj_t palette_index_obj, mp_obj_t palette_value_obj) { + displayio_ondiskbitmap_t *self = MP_OBJ_TO_PTR(self_in); + mp_int_t palette_index, palette_value; + if ((!mp_obj_get_int_maybe(palette_index_obj, &palette_index)) || + (!mp_obj_get_int_maybe(palette_value_obj, &palette_value))) { + mp_raise_ValueError(translate("palette_index, palette_value should be an int")); + } + common_hal_displayio_ondiskbitmap_set_palette(self, palette_index, palette_value); + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_3(displayio_ondiskbitmap_set_palette_obj, displayio_ondiskbitmap_obj_set_palette); + + STATIC const mp_rom_map_elem_t displayio_ondiskbitmap_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_ondiskbitmap_height_obj) }, { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_ondiskbitmap_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_palette_size), MP_ROM_PTR(&displayio_ondiskbitmap_palette_size_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_palette), MP_ROM_PTR(&displayio_ondiskbitmap_get_palette_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_palette), MP_ROM_PTR(&displayio_ondiskbitmap_set_palette_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_ondiskbitmap_locals_dict, displayio_ondiskbitmap_locals_dict_table); diff --git a/shared-bindings/displayio/OnDiskBitmap.h b/shared-bindings/displayio/OnDiskBitmap.h index aff3a19db2969..cb5ddaaa04c05 100644 --- a/shared-bindings/displayio/OnDiskBitmap.h +++ b/shared-bindings/displayio/OnDiskBitmap.h @@ -40,4 +40,14 @@ uint32_t common_hal_displayio_ondiskbitmap_get_pixel(displayio_ondiskbitmap_t *b uint16_t common_hal_displayio_ondiskbitmap_get_height(displayio_ondiskbitmap_t *self); uint16_t common_hal_displayio_ondiskbitmap_get_width(displayio_ondiskbitmap_t *self); + +uint16_t common_hal_displayio_ondiskbitmap_palette_size(displayio_ondiskbitmap_t *self); + +uint32_t common_hal_displayio_ondiskbitmap_get_palette(displayio_ondiskbitmap_t *self, uint32_t palette_index); + +void common_hal_displayio_ondiskbitmap_set_palette(displayio_ondiskbitmap_t *self, uint32_t palette_index, uint32_t palette_value); + +bool displayio_ondiskbitmap_needs_refresh(displayio_ondiskbitmap_t *self); + +void displayio_ondiskbitmap_finish_refresh(displayio_ondiskbitmap_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_ONDISKBITMAP_H diff --git a/shared-module/displayio/OnDiskBitmap.c b/shared-module/displayio/OnDiskBitmap.c index 5c7e00a5839a7..660430e7d6594 100644 --- a/shared-module/displayio/OnDiskBitmap.c +++ b/shared-module/displayio/OnDiskBitmap.c @@ -62,6 +62,8 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, self->bits_per_pixel = bits_per_pixel; self->width = read_word(bmp_header, 9); self->height = read_word(bmp_header, 11); + self->palette_size = 0; + self->full_refresh = true; if (bits_per_pixel == 16) { if (((header_size >= 56)) || (self->bitfield_compressed)) { @@ -78,19 +80,19 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, if (number_of_colors == 0) { number_of_colors = 1 << bits_per_pixel; } - uint16_t palette_size = number_of_colors * sizeof(uint32_t); + self->palette_size = number_of_colors * sizeof(uint32_t); uint16_t palette_offset = 0xe + header_size; - self->palette_data = m_malloc(palette_size, false); + self->palette_data = (uint32_t *)m_malloc(self->palette_size, false); f_rewind(&self->file->fp); f_lseek(&self->file->fp, palette_offset); UINT palette_bytes_read; - if (f_read(&self->file->fp, self->palette_data, palette_size, &palette_bytes_read) != FR_OK) { + if (f_read(&self->file->fp, self->palette_data, self->palette_size, &palette_bytes_read) != FR_OK) { mp_raise_OSError(MP_EIO); } - if (palette_bytes_read != palette_size) { + if (palette_bytes_read != self->palette_size) { mp_raise_ValueError(translate("Unable to read color palette data")); } } else if (!(header_size == 12 || header_size == 40 || header_size == 108 || header_size == 124)) { @@ -185,3 +187,37 @@ uint16_t common_hal_displayio_ondiskbitmap_get_height(displayio_ondiskbitmap_t * uint16_t common_hal_displayio_ondiskbitmap_get_width(displayio_ondiskbitmap_t *self) { return self->width; } + +uint16_t common_hal_displayio_ondiskbitmap_palette_size(displayio_ondiskbitmap_t *self) { + return self->palette_size / sizeof(uint32_t); +} + +uint32_t common_hal_displayio_ondiskbitmap_get_palette(displayio_ondiskbitmap_t *self, uint32_t palette_index) { + if (self->palette_size == 0) { + mp_raise_ValueError(translate("this OnDiskBitmap is raw color, not indexed")); + } + if (self->palette_size <= (palette_index * sizeof(uint32_t))) { + mp_raise_ValueError(translate("index is outside OnDiskBitmap palette size")); + } + + return self->palette_data[palette_index]; +} + +void common_hal_displayio_ondiskbitmap_set_palette(displayio_ondiskbitmap_t *self, uint32_t palette_index, uint32_t palette_value) { + if (self->palette_size == 0) { + mp_raise_ValueError(translate("OnDiskBitmap is raw color, not indexed")); + } + if ((self->palette_size <= (palette_index * sizeof(uint32_t))) || (palette_index < 0)) { + mp_raise_ValueError(translate("index is outside of palette size")); + } + self->palette_data[palette_index] = palette_value; + self->full_refresh = true; +} + +bool displayio_ondiskbitmap_needs_refresh(displayio_ondiskbitmap_t *self) { + return self->full_refresh; +} + +void displayio_ondiskbitmap_finish_refresh(displayio_ondiskbitmap_t *self) { + self->full_refresh = false; +} diff --git a/shared-module/displayio/OnDiskBitmap.h b/shared-module/displayio/OnDiskBitmap.h index 610b1149105b5..c35148cf722c7 100644 --- a/shared-module/displayio/OnDiskBitmap.h +++ b/shared-module/displayio/OnDiskBitmap.h @@ -46,7 +46,9 @@ typedef struct { bool bitfield_compressed; pyb_file_obj_t *file; uint8_t bits_per_pixel; + uint16_t palette_size; uint32_t *palette_data; + bool full_refresh; } displayio_ondiskbitmap_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_ONDISKBITMAP_H diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index 347eba577edb2..1d6e198e9e1ca 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -522,8 +522,9 @@ void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self) { } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) { displayio_shape_finish_refresh(self->bitmap); } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) { - // OnDiskBitmap changes will trigger a complete reload so no need to - // track changes. + displayio_ondiskbitmap_finish_refresh(self->bitmap); + // + // OnDiskBitmap palette changes will need a complete reload. } // TODO(tannewt): We could double buffer changes to position and move them over here. // That way they won't change during a refresh and tear. @@ -576,7 +577,9 @@ displayio_area_t *displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *sel (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type) && displayio_palette_needs_refresh(self->pixel_shader)) || (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type) && - displayio_colorconverter_needs_refresh(self->pixel_shader)); + displayio_colorconverter_needs_refresh(self->pixel_shader)) || + (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type) && + displayio_ondiskbitmap_needs_refresh(self->bitmap)); if (self->full_change || first_draw) { self->current_area.next = tail; return &self->current_area;