From c6dbc7df3a053c4bc40bb9945d12746fb9a8f4f2 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 12 Nov 2021 10:30:40 -0600 Subject: [PATCH] Add displayio bitmaps to unix build --- ...ayio_colorspace_only.c => displayio_min.c} | 4 +- .../unix/variants/coverage/mpconfigvariant.mk | 16 +- py/circuitpy_defns.mk | 1 + shared-bindings/displayio/Bitmap.c | 7 +- shared-bindings/displayio/area.c | 0 shared-module/displayio/Bitmap.c | 8 +- shared-module/displayio/__init__.c | 158 +++-------------- shared-module/displayio/area.c | 161 ++++++++++++++++++ shared-module/displayio/area.h | 5 +- 9 files changed, 215 insertions(+), 145 deletions(-) rename ports/unix/{displayio_colorspace_only.c => displayio_min.c} (97%) create mode 100644 shared-bindings/displayio/area.c create mode 100644 shared-module/displayio/area.c diff --git a/ports/unix/displayio_colorspace_only.c b/ports/unix/displayio_min.c similarity index 97% rename from ports/unix/displayio_colorspace_only.c rename to ports/unix/displayio_min.c index 40325ec76a..debca1e088 100644 --- a/ports/unix/displayio_colorspace_only.c +++ b/ports/unix/displayio_min.c @@ -29,6 +29,7 @@ #include "py/runtime.h" #include "shared-bindings/displayio/__init__.h" +#include "shared-bindings/displayio/Bitmap.h" MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB888, DISPLAYIO_COLORSPACE_RGB888); MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, RGB565, DISPLAYIO_COLORSPACE_RGB565); @@ -78,6 +79,7 @@ MAKE_ENUM_TYPE(displayio, ColorSpace, displayio_colorspace); STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_displayio) }, + { MP_ROM_QSTR(MP_QSTR_Bitmap), MP_ROM_PTR(&displayio_bitmap_type) }, { MP_ROM_QSTR(MP_QSTR_Colorspace), MP_ROM_PTR(&displayio_colorspace_type) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_module_globals, displayio_module_globals_table); @@ -87,4 +89,4 @@ const mp_obj_module_t displayio_module = { .globals = (mp_obj_dict_t *)&displayio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_displayio, displayio_module, CIRCUITPY_DISPLAYIO_COLORSPACE_ONLY); +MP_REGISTER_MODULE(MP_QSTR_displayio, displayio_module, CIRCUITPY_DISPLAYIO_UNIX); diff --git a/ports/unix/variants/coverage/mpconfigvariant.mk b/ports/unix/variants/coverage/mpconfigvariant.mk index e614cd411e..5465e50cfc 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.mk +++ b/ports/unix/variants/coverage/mpconfigvariant.mk @@ -27,10 +27,20 @@ SRC_C += $(SRC_QRIO) CFLAGS += -DCIRCUITPY_QRIO=1 $(BUILD)/lib/quirc/lib/%.o: CFLAGS += -Wno-shadow -Wno-sign-compare -include shared-module/qrio/quirc_alloc.h -SRC_GIFIO := $(patsubst ../../%,%,$(wildcard ../../shared-bindings/gifio/*.c ../../shared-module/gifio/*.c)) shared/runtime/context_manager_helpers.c displayio_colorspace_only.c shared-module/displayio/ColorConverter.c shared-bindings/util.c -SRC_C += $(SRC_GIFIO) +SRC_BITMAP := \ + $(patsubst ../../%,%,$(wildcard ../../shared-bindings/gifio/*.c ../../shared-module/gifio/*.c)) \ + shared/runtime/context_manager_helpers.c \ + displayio_min.c \ + shared-bindings/displayio/Bitmap.c \ + shared-module/displayio/area.c \ + shared-module/displayio/Bitmap.c \ + shared-module/displayio/ColorConverter.c \ + shared-bindings/util.c \ -CFLAGS += -DCIRCUITPY_GIFIO=1 -DCIRCUITPY_DISPLAYIO_COLORSPACE_ONLY=1 +$(info $(SRC_BITMAP)) +SRC_C += $(SRC_BITMAP) + +CFLAGS += -DCIRCUITPY_GIFIO=1 -DCIRCUITPY_DISPLAYIO_UNIX=1 SRC_C += coverage.c SRC_CXX += coveragecpp.cpp diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index fec2512baf..68b529a05f 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -534,6 +534,7 @@ SRC_SHARED_MODULE_ALL = \ displayio/Palette.c \ displayio/Shape.c \ displayio/TileGrid.c \ + displayio/area.c \ displayio/__init__.c \ fontio/BuiltinFont.c \ fontio/__init__.c \ diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index 5a1e12189a..f042ae27e2 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -33,7 +33,6 @@ #include "py/binary.h" #include "py/objproperty.h" #include "py/runtime.h" -#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/util.h" #include "supervisor/shared/translate.h" @@ -206,9 +205,9 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val STATIC mp_obj_t displayio_bitmap_obj_blit(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum {ARG_x, ARG_y, ARG_source, ARG_x1, ARG_y1, ARG_x2, ARG_y2, ARG_skip_index}; static const mp_arg_t allowed_args[] = { - {MP_QSTR_x, MP_ARG_REQUIRED | MP_ARG_INT}, - {MP_QSTR_y, MP_ARG_REQUIRED | MP_ARG_INT}, - {MP_QSTR_source_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ}, + {MP_QSTR_x, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = 0} }, + {MP_QSTR_y, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = 0} }, + {MP_QSTR_source_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = 0} }, {MP_QSTR_x1, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, {MP_QSTR_y1, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, {MP_QSTR_x2, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, // None convert to source->width diff --git a/shared-bindings/displayio/area.c b/shared-bindings/displayio/area.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index e218049b6c..a18ba7a48a 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -113,7 +113,7 @@ void displayio_bitmap_set_dirty_area(displayio_bitmap_t *self, const displayio_a displayio_area_t area = *dirty_area; displayio_area_canon(&area); displayio_area_union(&area, &self->dirty_area, &area); - displayio_area_t bitmap_area = {0, 0, self->width, self->height}; + displayio_area_t bitmap_area = {0, 0, self->width, self->height, NULL}; displayio_area_compute_overlap(&area, &bitmap_area, &self->dirty_area); } @@ -160,7 +160,7 @@ void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16 dirty_y_max = self->height; } - displayio_area_t a = { x, y, dirty_x_max, dirty_y_max}; + displayio_area_t a = { x, y, dirty_x_max, dirty_y_max, NULL}; displayio_bitmap_set_dirty_area(self, &a); bool x_reverse = false; @@ -199,7 +199,7 @@ void common_hal_displayio_bitmap_blit(displayio_bitmap_t *self, int16_t x, int16 void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x, int16_t y, uint32_t value) { // update the dirty region - displayio_area_t a = {x, y, x + 1, y + 1}; + displayio_area_t a = {x, y, x + 1, y + 1, NULL}; displayio_bitmap_set_dirty_area(self, &a); // write the pixel @@ -221,7 +221,7 @@ void displayio_bitmap_finish_refresh(displayio_bitmap_t *self) { } void common_hal_displayio_bitmap_fill(displayio_bitmap_t *self, uint32_t value) { - displayio_area_t a = {0, 0, self->width, self->height}; + displayio_area_t a = {0, 0, self->width, self->height, NULL}; displayio_bitmap_set_dirty_area(self, &a); // build the packed word diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index e4a4965368..eff86b81df 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -1,3 +1,29 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include @@ -249,138 +275,6 @@ void displayio_gc_collect(void) { } } -void displayio_area_copy(const displayio_area_t *src, displayio_area_t *dst) { - dst->x1 = src->x1; - dst->y1 = src->y1; - dst->x2 = src->x2; - dst->y2 = src->y2; -} - -void displayio_area_scale(displayio_area_t *area, uint16_t scale) { - area->x1 *= scale; - area->y1 *= scale; - area->x2 *= scale; - area->y2 *= scale; -} - -void displayio_area_shift(displayio_area_t *area, int16_t dx, int16_t dy) { - area->x1 += dx; - area->y1 += dy; - area->x2 += dx; - area->y2 += dy; -} - -bool displayio_area_compute_overlap(const displayio_area_t *a, - const displayio_area_t *b, - displayio_area_t *overlap) { - overlap->x1 = a->x1; - if (b->x1 > overlap->x1) { - overlap->x1 = b->x1; - } - overlap->x2 = a->x2; - if (b->x2 < overlap->x2) { - overlap->x2 = b->x2; - } - if (overlap->x1 >= overlap->x2) { - return false; - } - overlap->y1 = a->y1; - if (b->y1 > overlap->y1) { - overlap->y1 = b->y1; - } - overlap->y2 = a->y2; - if (b->y2 < overlap->y2) { - overlap->y2 = b->y2; - } - if (overlap->y1 >= overlap->y2) { - return false; - } - return true; -} - -bool displayio_area_empty(const displayio_area_t *a) { - return (a->x1 == a->x2) || (a->y1 == a->y2); -} - -void displayio_area_canon(displayio_area_t *a) { - if (a->x1 > a->x2) { - int16_t t = a->x1; - a->x1 = a->x2; - a->x2 = t; - } - if (a->y1 > a->y2) { - int16_t t = a->y1; - a->y1 = a->y2; - a->y2 = t; - } -} - -void displayio_area_union(const displayio_area_t *a, - const displayio_area_t *b, - displayio_area_t *u) { - - if (displayio_area_empty(a)) { - displayio_area_copy(b, u); - return; - } - if (displayio_area_empty(b)) { - displayio_area_copy(a, u); - return; - } - u->x1 = MIN(a->x1, b->x1); - u->y1 = MIN(a->y1, b->y1); - u->x2 = MAX(a->x2, b->x2); - u->y2 = MAX(a->y2, b->y2); -} - -uint16_t displayio_area_width(const displayio_area_t *area) { - return area->x2 - area->x1; -} - -uint16_t displayio_area_height(const displayio_area_t *area) { - return area->y2 - area->y1; -} - -uint32_t displayio_area_size(const displayio_area_t *area) { - return displayio_area_width(area) * displayio_area_height(area); -} - -bool displayio_area_equal(const displayio_area_t *a, const displayio_area_t *b) { - return a->x1 == b->x1 && - a->y1 == b->y1 && - a->x2 == b->x2 && - a->y2 == b->y2; -} - -// Original and whole must be in the same coordinate space. -void displayio_area_transform_within(bool mirror_x, bool mirror_y, bool transpose_xy, - const displayio_area_t *original, - const displayio_area_t *whole, - displayio_area_t *transformed) { - if (mirror_x) { - transformed->x1 = whole->x1 + (whole->x2 - original->x2); - transformed->x2 = whole->x2 - (original->x1 - whole->x1); - } else { - transformed->x1 = original->x1; - transformed->x2 = original->x2; - } - if (mirror_y) { - transformed->y1 = whole->y1 + (whole->y2 - original->y2); - transformed->y2 = whole->y2 - (original->y1 - whole->y1); - } else { - transformed->y1 = original->y1; - transformed->y2 = original->y2; - } - if (transpose_xy) { - int16_t y1 = transformed->y1; - int16_t y2 = transformed->y2; - transformed->y1 = whole->y1 + (transformed->x1 - whole->x1); - transformed->y2 = whole->y1 + (transformed->x2 - whole->x1); - transformed->x2 = whole->x1 + (y2 - whole->y1); - transformed->x1 = whole->x1 + (y1 - whole->y1); - } -} - primary_display_t *allocate_display(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { mp_const_obj_t display_type = displays[i].display.base.type; diff --git a/shared-module/displayio/area.c b/shared-module/displayio/area.c new file mode 100644 index 0000000000..6d0f94d9cc --- /dev/null +++ b/shared-module/displayio/area.c @@ -0,0 +1,161 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-module/displayio/area.h" + +#include "py/misc.h" + +void displayio_area_copy(const displayio_area_t *src, displayio_area_t *dst) { + dst->x1 = src->x1; + dst->y1 = src->y1; + dst->x2 = src->x2; + dst->y2 = src->y2; +} + +void displayio_area_scale(displayio_area_t *area, uint16_t scale) { + area->x1 *= scale; + area->y1 *= scale; + area->x2 *= scale; + area->y2 *= scale; +} + +void displayio_area_shift(displayio_area_t *area, int16_t dx, int16_t dy) { + area->x1 += dx; + area->y1 += dy; + area->x2 += dx; + area->y2 += dy; +} + +bool displayio_area_compute_overlap(const displayio_area_t *a, + const displayio_area_t *b, + displayio_area_t *overlap) { + overlap->x1 = a->x1; + if (b->x1 > overlap->x1) { + overlap->x1 = b->x1; + } + overlap->x2 = a->x2; + if (b->x2 < overlap->x2) { + overlap->x2 = b->x2; + } + if (overlap->x1 >= overlap->x2) { + return false; + } + overlap->y1 = a->y1; + if (b->y1 > overlap->y1) { + overlap->y1 = b->y1; + } + overlap->y2 = a->y2; + if (b->y2 < overlap->y2) { + overlap->y2 = b->y2; + } + if (overlap->y1 >= overlap->y2) { + return false; + } + return true; +} + +bool displayio_area_empty(const displayio_area_t *a) { + return (a->x1 == a->x2) || (a->y1 == a->y2); +} + +void displayio_area_canon(displayio_area_t *a) { + if (a->x1 > a->x2) { + int16_t t = a->x1; + a->x1 = a->x2; + a->x2 = t; + } + if (a->y1 > a->y2) { + int16_t t = a->y1; + a->y1 = a->y2; + a->y2 = t; + } +} + +void displayio_area_union(const displayio_area_t *a, + const displayio_area_t *b, + displayio_area_t *u) { + + if (displayio_area_empty(a)) { + displayio_area_copy(b, u); + return; + } + if (displayio_area_empty(b)) { + displayio_area_copy(a, u); + return; + } + u->x1 = MIN(a->x1, b->x1); + u->y1 = MIN(a->y1, b->y1); + u->x2 = MAX(a->x2, b->x2); + u->y2 = MAX(a->y2, b->y2); +} + +uint16_t displayio_area_width(const displayio_area_t *area) { + return area->x2 - area->x1; +} + +uint16_t displayio_area_height(const displayio_area_t *area) { + return area->y2 - area->y1; +} + +uint32_t displayio_area_size(const displayio_area_t *area) { + return displayio_area_width(area) * displayio_area_height(area); +} + +bool displayio_area_equal(const displayio_area_t *a, const displayio_area_t *b) { + return a->x1 == b->x1 && + a->y1 == b->y1 && + a->x2 == b->x2 && + a->y2 == b->y2; +} + +// Original and whole must be in the same coordinate space. +void displayio_area_transform_within(bool mirror_x, bool mirror_y, bool transpose_xy, + const displayio_area_t *original, + const displayio_area_t *whole, + displayio_area_t *transformed) { + if (mirror_x) { + transformed->x1 = whole->x1 + (whole->x2 - original->x2); + transformed->x2 = whole->x2 - (original->x1 - whole->x1); + } else { + transformed->x1 = original->x1; + transformed->x2 = original->x2; + } + if (mirror_y) { + transformed->y1 = whole->y1 + (whole->y2 - original->y2); + transformed->y2 = whole->y2 - (original->y1 - whole->y1); + } else { + transformed->y1 = original->y1; + transformed->y2 = original->y2; + } + if (transpose_xy) { + int16_t y1 = transformed->y1; + int16_t y2 = transformed->y2; + transformed->y1 = whole->y1 + (transformed->x1 - whole->x1); + transformed->y2 = whole->y1 + (transformed->x2 - whole->x1); + transformed->x2 = whole->x1 + (y2 - whole->y1); + transformed->x1 = whole->x1 + (y1 - whole->y1); + } +} diff --git a/shared-module/displayio/area.h b/shared-module/displayio/area.h index 6a8ad6ceb0..47cb48bcdd 100644 --- a/shared-module/displayio/area.h +++ b/shared-module/displayio/area.h @@ -27,7 +27,10 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_AREA_H #define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_AREA_H -// Implementations are in __init__.c +#include +#include + +// Implementations are in area.c typedef struct _displayio_area_t displayio_area_t; struct _displayio_area_t {