Skip to content

Commit a14762a

Browse files
committed
Add support for rendering a shape.
Fixes adafruit#1171
1 parent 738e8f0 commit a14762a

9 files changed

Lines changed: 307 additions & 1 deletion

File tree

ports/atmel-samd/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ SRC_SHARED_MODULE = \
382382
displayio/Group.c \
383383
displayio/OnDiskBitmap.c \
384384
displayio/Palette.c \
385+
displayio/Shape.c \
385386
displayio/Sprite.c \
386387
gamepad/__init__.c \
387388
gamepad/GamePad.c \

ports/atmel-samd/common-hal/displayio/FourWire.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ bool common_hal_displayio_fourwire_begin_transaction(displayio_fourwire_obj_t* s
7070
return false;
7171
}
7272
// TODO(tannewt): Stop hardcoding SPI frequency, polarity and phase.
73-
common_hal_busio_spi_configure(&self->bus, 12000000, 0, 0, 8);
73+
common_hal_busio_spi_configure(&self->bus, 48000000, 0, 0, 8);
7474
common_hal_digitalio_digitalinout_set_value(&self->chip_select, false);
7575
return true;
7676
}

shared-bindings/displayio/Shape.c

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "shared-bindings/displayio/Shape.h"
28+
29+
#include <stdint.h>
30+
31+
#include "py/binary.h"
32+
#include "py/objproperty.h"
33+
#include "py/runtime.h"
34+
#include "shared-bindings/util.h"
35+
#include "supervisor/shared/translate.h"
36+
37+
//| .. currentmodule:: displayio
38+
//|
39+
//| :class:`Shape` -- Represents a shape by defining its bounds on each row
40+
//| ==========================================================================
41+
//|
42+
//| Represents any shape made by defining boundaries that may be mirrored.
43+
//|
44+
//| .. warning:: This will likely be changed before 4.0.0. Consider it very experimental.
45+
//|
46+
//| .. class:: Shape(width, height, *, mirror_x=False, mirrored_y=False)
47+
//|
48+
//| Create a Shape object with the given fixed size. Each pixel is one bit and is stored by the
49+
//| column boundaries of the shape on each row. Each row's boundary defaults to the full row.
50+
//|
51+
//| :param int width: The number of pixels wide
52+
//| :param int height: The number of pixels high
53+
//| :param bool mirror_x: When true the left boundary is mirrored to the right.
54+
//| :param bool mirror_y: When true the top boundary is mirrored to the bottom.
55+
//|
56+
STATIC mp_obj_t displayio_shape_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
57+
mp_arg_check_num(n_args, n_kw, 2, 4, true);
58+
mp_map_t kw_args;
59+
mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
60+
enum { ARG_width, ARG_height, ARG_mirror_x, ARG_mirror_y };
61+
static const mp_arg_t allowed_args[] = {
62+
{ MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED },
63+
{ MP_QSTR_height, MP_ARG_INT | MP_ARG_REQUIRED },
64+
{ MP_QSTR_mirror_x, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
65+
{ MP_QSTR_mirror_y, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
66+
};
67+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
68+
mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
69+
70+
displayio_shape_t *self = m_new_obj(displayio_shape_t);
71+
self->base.type = &displayio_shape_type;
72+
common_hal_displayio_shape_construct(self,
73+
args[ARG_width].u_int,
74+
args[ARG_height].u_int,
75+
args[ARG_mirror_x].u_bool,
76+
args[ARG_mirror_y].u_bool);
77+
78+
return MP_OBJ_FROM_PTR(self);
79+
}
80+
81+
82+
//| .. method:: set_boundary(y, start_x, end_x)
83+
//|
84+
//| Loads pre-packed data into the given row.
85+
//|
86+
STATIC mp_obj_t displayio_shape_obj_set_boundary(size_t n_args, const mp_obj_t *args) {
87+
(void) n_args;
88+
displayio_shape_t *self = MP_OBJ_TO_PTR(args[0]);
89+
mp_int_t y;
90+
if (!mp_obj_get_int_maybe(args[1], &y)) {
91+
mp_raise_ValueError(translate("y should be an int"));
92+
}
93+
mp_int_t start_x;
94+
if (!mp_obj_get_int_maybe(args[2], &start_x)) {
95+
mp_raise_ValueError(translate("start_x should be an int"));
96+
}
97+
mp_int_t end_x;
98+
if (!mp_obj_get_int_maybe(args[3], &end_x)) {
99+
mp_raise_ValueError(translate("end_x should be an int"));
100+
}
101+
common_hal_displayio_shape_set_boundary(self, y, start_x, end_x);
102+
103+
return mp_const_none;
104+
}
105+
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(displayio_shape_set_boundary_obj, 4, 4, displayio_shape_obj_set_boundary);
106+
107+
STATIC const mp_rom_map_elem_t displayio_shape_locals_dict_table[] = {
108+
{ MP_ROM_QSTR(MP_QSTR_set_boundary), MP_ROM_PTR(&displayio_shape_set_boundary_obj) },
109+
};
110+
STATIC MP_DEFINE_CONST_DICT(displayio_shape_locals_dict, displayio_shape_locals_dict_table);
111+
112+
const mp_obj_type_t displayio_shape_type = {
113+
{ &mp_type_type },
114+
.name = MP_QSTR_Shape,
115+
.make_new = displayio_shape_make_new,
116+
.locals_dict = (mp_obj_dict_t*)&displayio_shape_locals_dict,
117+
};

shared-bindings/displayio/Shape.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_SHAPE_H
28+
#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_SHAPE_H
29+
30+
#include "shared-module/displayio/Shape.h"
31+
32+
extern const mp_obj_type_t displayio_shape_type;
33+
34+
void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t width,
35+
uint32_t height, bool mirror_x, bool mirror_y);
36+
37+
void common_hal_displayio_shape_set_boundary(displayio_shape_t *self, uint16_t y, uint16_t start_x,
38+
uint16_t end_x);
39+
uint32_t common_hal_displayio_shape_get_pixel(void *shape, int16_t x, int16_t y);
40+
41+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_SHAPE_H

shared-bindings/displayio/Sprite.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "shared-bindings/displayio/ColorConverter.h"
3737
#include "shared-bindings/displayio/OnDiskBitmap.h"
3838
#include "shared-bindings/displayio/Palette.h"
39+
#include "shared-bindings/displayio/Shape.h"
3940
#include "supervisor/shared/translate.h"
4041

4142
void unpack_position(mp_obj_t position_obj, int16_t* x, int16_t* y) {
@@ -93,6 +94,10 @@ STATIC mp_obj_t displayio_sprite_make_new(const mp_obj_type_t *type, size_t n_ar
9394
displayio_ondiskbitmap_t* bmp = MP_OBJ_TO_PTR(bitmap);
9495
width = bmp->width;
9596
height = bmp->height;
97+
} else if (MP_OBJ_IS_TYPE(bitmap, &displayio_shape_type)) {
98+
displayio_shape_t* bmp = MP_OBJ_TO_PTR(bitmap);
99+
width = bmp->width;
100+
height = bmp->height;
96101
} else {
97102
mp_raise_TypeError(translate("unsupported bitmap type"));
98103
}

shared-bindings/displayio/__init__.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "shared-bindings/displayio/Group.h"
3737
#include "shared-bindings/displayio/OnDiskBitmap.h"
3838
#include "shared-bindings/displayio/Palette.h"
39+
#include "shared-bindings/displayio/Shape.h"
3940
#include "shared-bindings/displayio/Sprite.h"
4041

4142
//| :mod:`displayio` --- Native display driving
@@ -64,6 +65,7 @@
6465
//| Group
6566
//| OnDiskBitmap
6667
//| Palette
68+
//| Shape
6769
//| Sprite
6870
//|
6971
//| All libraries change hardware state but are never deinit
@@ -76,6 +78,7 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = {
7678
{ MP_ROM_QSTR(MP_QSTR_Group), MP_ROM_PTR(&displayio_group_type) },
7779
{ MP_ROM_QSTR(MP_QSTR_OnDiskBitmap), MP_ROM_PTR(&displayio_ondiskbitmap_type) },
7880
{ MP_ROM_QSTR(MP_QSTR_Palette), MP_ROM_PTR(&displayio_palette_type) },
81+
{ MP_ROM_QSTR(MP_QSTR_Shape), MP_ROM_PTR(&displayio_shape_type) },
7982
{ MP_ROM_QSTR(MP_QSTR_Sprite), MP_ROM_PTR(&displayio_sprite_type) },
8083

8184
{ MP_ROM_QSTR(MP_QSTR_FourWire), MP_ROM_PTR(&displayio_fourwire_type) },

shared-module/displayio/Shape.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "shared-bindings/displayio/Shape.h"
28+
29+
#include <string.h>
30+
31+
#include "py/runtime.h"
32+
33+
void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t width,
34+
uint32_t height, bool mirror_x, bool mirror_y) {
35+
self->mirror_x = mirror_x;
36+
self->mirror_y = mirror_y;
37+
self->width = width;
38+
if (self->mirror_x) {
39+
width /= 2;
40+
width += self->width % 2 - 1;
41+
}
42+
self->half_width = width;
43+
44+
self->height = height;
45+
if (self->mirror_y) {
46+
height /= 2;
47+
height += self->height % 2 - 1;
48+
}
49+
self->half_height = height;
50+
51+
self->data = m_malloc(height * sizeof(uint32_t), false);
52+
for (uint16_t i = 0; i < height; i++) {
53+
self->data[2 * i] = 0;
54+
self->data[2 * i + 1] = width;
55+
}
56+
}
57+
58+
void common_hal_displayio_shape_set_boundary(displayio_shape_t *self, uint16_t y, uint16_t start_x, uint16_t end_x) {
59+
if (y < 0 || y >= self->height || (self->mirror_y && y > self->half_height)) {
60+
mp_raise_ValueError(translate("y value out of bounds"));
61+
}
62+
if (start_x < 0 || start_x > self->width || end_x < 0 || end_x > self->height) {
63+
mp_raise_ValueError(translate("x value out of bounds"));
64+
}
65+
uint16_t half_width = self->width / 2 - 1 + self->width % 2;
66+
if (self->mirror_x && (start_x > half_width || end_x > half_width)) {
67+
mp_raise_ValueError_varg(translate("Maximum x value when mirrored is %d"), half_width);
68+
}
69+
self->data[2 * y] = start_x;
70+
self->data[2 * y + 1] = end_x;
71+
}
72+
73+
uint32_t common_hal_displayio_shape_get_pixel(void *obj, int16_t x, int16_t y) {
74+
displayio_shape_t *self = obj;
75+
if (x >= self->width || x < 0 || y >= self->height || y < 0) {
76+
return 0;
77+
}
78+
if (self->mirror_x && x > self->half_width) {
79+
x = self->width - 1 - x;
80+
}
81+
if (self->mirror_y && y > self->half_height) {
82+
y = self->height - y - 1;
83+
}
84+
uint16_t start_x = self->data[2 * y];
85+
uint16_t end_x = self->data[2 * y + 1];
86+
if (x < start_x || x > end_x) {
87+
return 0;
88+
}
89+
return 1;
90+
}

shared-module/displayio/Shape.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SHAPE_H
28+
#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SHAPE_H
29+
30+
#include <stdbool.h>
31+
#include <stdint.h>
32+
33+
#include "py/obj.h"
34+
35+
typedef struct {
36+
mp_obj_base_t base;
37+
uint16_t width;
38+
uint16_t height;
39+
uint16_t half_width;
40+
uint16_t half_height;
41+
uint16_t* data;
42+
bool mirror_x;
43+
bool mirror_y;
44+
} displayio_shape_t;
45+
46+
#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SHAPE_H

shared-module/displayio/Sprite.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "shared-bindings/displayio/ColorConverter.h"
3131
#include "shared-bindings/displayio/OnDiskBitmap.h"
3232
#include "shared-bindings/displayio/Palette.h"
33+
#include "shared-bindings/displayio/Shape.h"
3334

3435
void common_hal_displayio_sprite_construct(displayio_sprite_t *self, mp_obj_t bitmap,
3536
mp_obj_t pixel_shader, uint16_t width, uint16_t height, uint16_t x, uint16_t y) {
@@ -71,6 +72,8 @@ bool displayio_sprite_get_pixel(displayio_sprite_t *self, int16_t x, int16_t y,
7172
uint32_t value = 0;
7273
if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) {
7374
value = common_hal_displayio_bitmap_get_pixel(self->bitmap, x, y);
75+
} else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) {
76+
value = common_hal_displayio_shape_get_pixel(self->bitmap, x, y);
7477
} else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) {
7578
value = common_hal_displayio_ondiskbitmap_get_pixel(self->bitmap, x, y);
7679
}

0 commit comments

Comments
 (0)