Skip to content

Commit 8607cdd

Browse files
committed
vectorio: add draw protocol
* Removes VectorShape from user python interactions * Re-integrates vectorio with displayio behind draw protocol implementations * Implements draw protocol with VectorShape * Composes VectorShape behaviors into Rectangle, Circle and Polygon * Fixes terrible pixel garbage being left behind * Improves redraw performance (heuristically) by tracking dirty area separately from current area. Known Issues: It does not work with transposed views.
1 parent 1b67b91 commit 8607cdd

File tree

19 files changed

+374
-156
lines changed

19 files changed

+374
-156
lines changed

shared-bindings/vectorio/Circle.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
1+
#include "shared-bindings/vectorio/__init__.h"
22
#include "shared-bindings/vectorio/Circle.h"
3+
#include "shared-bindings/vectorio/VectorShape.h"
34

45

56
#include <stdint.h>
@@ -11,15 +12,21 @@
1112

1213
//| class Circle:
1314
//|
14-
//| def __init__(self, radius: int) -> None:
15+
//| def __init__(self, pixel_shader: Union[ColorConverter, Palette] radius: int, x: int, y: int) -> None:
1516
//| """Circle is positioned on screen by its center point.
1617
//|
17-
//| :param radius: The radius of the circle in pixels"""
18+
//| :param pixel_shader: The pixel shader that produces colors from values
19+
//| :param radius: The radius of the circle in pixels
20+
//| :param x: Initial x position of the axis.
21+
//| :param y: Initial y position of the axis."""
1822
//|
1923
static mp_obj_t vectorio_circle_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
20-
enum { ARG_radius };
24+
enum { ARG_pixel_shader, ARG_radius, ARG_x, ARG_y };
2125
static const mp_arg_t allowed_args[] = {
26+
{ MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
2227
{ MP_QSTR_radius, MP_ARG_REQUIRED | MP_ARG_INT },
28+
{ MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
29+
{ MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
2330
};
2431
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
2532
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -33,9 +40,22 @@ static mp_obj_t vectorio_circle_make_new(const mp_obj_type_t *type, size_t n_arg
3340
self->base.type = &vectorio_circle_type;
3441
common_hal_vectorio_circle_construct(self, radius);
3542

43+
// VectorShape parts
44+
mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj;
45+
int16_t x = args[ARG_x].u_int;
46+
int16_t y = args[ARG_y].u_int;
47+
mp_obj_t vector_shape = vectorio_vector_shape_make_new(self, pixel_shader, x, y);
48+
self->draw_protocol_instance = vector_shape;
49+
3650
return MP_OBJ_FROM_PTR(self);
3751
}
3852

53+
STATIC const vectorio_draw_protocol_t circle_draw_protocol = {
54+
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_draw)
55+
.draw_get_protocol_self = (draw_get_protocol_self_fun)common_hal_vectorio_circle_get_draw_protocol,
56+
.draw_protocol_impl = &vectorio_vector_shape_draw_protocol_impl
57+
};
58+
3959

4060
//| radius : int
4161
//| """The radius of the circle in pixels."""
@@ -62,13 +82,21 @@ const mp_obj_property_t vectorio_circle_radius_obj = {
6282

6383

6484
STATIC const mp_rom_map_elem_t vectorio_circle_locals_dict_table[] = {
85+
// Properties
6586
{ MP_ROM_QSTR(MP_QSTR_radius), MP_ROM_PTR(&vectorio_circle_radius_obj) },
87+
{ MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) },
88+
{ MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) },
89+
{ MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) },
6690
};
6791
STATIC MP_DEFINE_CONST_DICT(vectorio_circle_locals_dict, vectorio_circle_locals_dict_table);
6892

6993
const mp_obj_type_t vectorio_circle_type = {
7094
{ &mp_type_type },
7195
.name = MP_QSTR_Circle,
96+
.flags = MP_TYPE_FLAG_EXTENDED,
7297
.make_new = vectorio_circle_make_new,
7398
.locals_dict = (mp_obj_dict_t *)&vectorio_circle_locals_dict,
99+
MP_TYPE_EXTENDED_FIELDS(
100+
.protocol = &circle_draw_protocol,
101+
),
74102
};

shared-bindings/vectorio/Circle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ void common_hal_vectorio_circle_get_area(void *circle, displayio_area_t *out_are
1919
int16_t common_hal_vectorio_circle_get_radius(void *circle);
2020
void common_hal_vectorio_circle_set_radius(void *circle, int16_t radius);
2121

22+
mp_obj_t common_hal_vectorio_circle_get_draw_protocol(void *circle);
23+
2224
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_CIRCLE_H

shared-bindings/vectorio/Polygon.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
1+
#include "shared-bindings/vectorio/__init__.h"
22
#include "shared-module/vectorio/__init__.h"
33
#include "shared-bindings/vectorio/Polygon.h"
4+
#include "shared-bindings/vectorio/VectorShape.h"
45

56
#include <stdint.h>
67

@@ -16,15 +17,21 @@
1617

1718

1819
//| class Polygon:
19-
//| def __init__(self, points: List[Tuple[int, int]]) -> None:
20+
//| def __init__(self, pixel_shader: Union[ColorConverter, Palette], points: List[Tuple[int, int]], x: int, y: int) -> None:
2021
//| """Represents a closed shape by ordered vertices
2122
//|
22-
//| :param points: Vertices for the polygon"""
23+
//| :param pixel_shader: The pixel shader that produces colors from values
24+
//| :param points: Vertices for the polygon
25+
//| :param x: Initial screen x position of the 0,0 origin in the points list.
26+
//| :param y: Initial screen y position of the 0,0 origin in the points list."""
2327
//|
2428
static mp_obj_t vectorio_polygon_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
25-
enum { ARG_points_list };
29+
enum { ARG_pixel_shader, ARG_points_list, ARG_x, ARG_y };
2630
static const mp_arg_t allowed_args[] = {
31+
{ MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
2732
{ MP_QSTR_points, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
33+
{ MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
34+
{ MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
2835
};
2936
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
3037
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -38,9 +45,22 @@ static mp_obj_t vectorio_polygon_make_new(const mp_obj_type_t *type, size_t n_ar
3845

3946
common_hal_vectorio_polygon_construct(self, args[ARG_points_list].u_obj);
4047

48+
// VectorShape parts
49+
mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj;
50+
int16_t x = args[ARG_x].u_int;
51+
int16_t y = args[ARG_y].u_int;
52+
mp_obj_t vector_shape = vectorio_vector_shape_make_new(self, pixel_shader, x, y);
53+
self->draw_protocol_instance = vector_shape;
54+
4155
return MP_OBJ_FROM_PTR(self);
4256
}
4357

58+
STATIC const vectorio_draw_protocol_t polygon_draw_protocol = {
59+
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_draw)
60+
.draw_get_protocol_self = (draw_get_protocol_self_fun)common_hal_vectorio_polygon_get_draw_protocol,
61+
.draw_protocol_impl = &vectorio_vector_shape_draw_protocol_impl
62+
};
63+
4464

4565
//| points: List[Tuple[int, int]]
4666
//| """Set a new look and shape for this polygon"""
@@ -67,13 +87,21 @@ const mp_obj_property_t vectorio_polygon_points_obj = {
6787
};
6888

6989
STATIC const mp_rom_map_elem_t vectorio_polygon_locals_dict_table[] = {
90+
// Properties
7091
{ MP_ROM_QSTR(MP_QSTR_points), MP_ROM_PTR(&vectorio_polygon_points_obj) },
92+
{ MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) },
93+
{ MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) },
94+
{ MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) },
7195
};
7296
STATIC MP_DEFINE_CONST_DICT(vectorio_polygon_locals_dict, vectorio_polygon_locals_dict_table);
7397

7498
const mp_obj_type_t vectorio_polygon_type = {
7599
{ &mp_type_type },
76100
.name = MP_QSTR_Polygon,
101+
.flags = MP_TYPE_FLAG_EXTENDED,
77102
.make_new = vectorio_polygon_make_new,
78103
.locals_dict = (mp_obj_dict_t *)&vectorio_polygon_locals_dict,
104+
MP_TYPE_EXTENDED_FIELDS(
105+
.protocol = &polygon_draw_protocol,
106+
),
79107
};

shared-bindings/vectorio/Polygon.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@ void common_hal_vectorio_polygon_get_area(void *polygon, displayio_area_t *out_a
2020
mp_obj_t common_hal_vectorio_polygon_get_points(vectorio_polygon_t *self);
2121
void common_hal_vectorio_polygon_set_points(vectorio_polygon_t *self, mp_obj_t points_list);
2222

23+
mp_obj_t common_hal_vectorio_polygon_get_draw_protocol(void *polygon);
24+
2325

2426
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_POLYGON_H

shared-bindings/vectorio/Rectangle.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
1+
#include "shared-bindings/vectorio/__init__.h"
22
#include "shared-bindings/vectorio/Rectangle.h"
3+
#include "shared-module/vectorio/VectorShape.h"
4+
#include "shared-bindings/vectorio/VectorShape.h"
35

46
#include <stdint.h>
57

@@ -8,17 +10,23 @@
810
#include "supervisor/shared/translate.h"
911

1012
//| class Rectangle:
11-
//| def __init__(self, width: int, height: int) -> None:
13+
//| def __init__(self, pixel_shader: Union[ColorConverter, Palette], width: int, height: int, x: int, y: int) -> None:
1214
//| """Represents a rectangle by defining its bounds
1315
//|
16+
//| :param pixel_shader: The pixel shader that produces colors from values
1417
//| :param width: The number of pixels wide
15-
//| :param height: The number of pixels high"""
18+
//| :param height: The number of pixels high
19+
//| :param x: Initial x position of the top left corner.
20+
//| :param y: Initial y position of the top left corner."""
1621
//|
1722
static mp_obj_t vectorio_rectangle_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
18-
enum { ARG_width, ARG_height };
23+
enum { ARG_pixel_shader, ARG_width, ARG_height, ARG_x, ARG_y };
1924
static const mp_arg_t allowed_args[] = {
25+
{ MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
2026
{ MP_QSTR_width, MP_ARG_REQUIRED | MP_ARG_INT },
2127
{ MP_QSTR_height, MP_ARG_REQUIRED | MP_ARG_INT },
28+
{ MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
29+
{ MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
2230
};
2331
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
2432
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -36,17 +44,37 @@ static mp_obj_t vectorio_rectangle_make_new(const mp_obj_type_t *type, size_t n_
3644
self->base.type = &vectorio_rectangle_type;
3745
common_hal_vectorio_rectangle_construct(self, width, height);
3846

47+
// VectorShape parts
48+
mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj;
49+
int16_t x = args[ARG_x].u_int;
50+
int16_t y = args[ARG_y].u_int;
51+
mp_obj_t vector_shape = vectorio_vector_shape_make_new(self, pixel_shader, x, y);
52+
self->draw_protocol_instance = vector_shape;
53+
3954
return MP_OBJ_FROM_PTR(self);
4055
}
4156

57+
STATIC const vectorio_draw_protocol_t rectangle_draw_protocol = {
58+
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_draw)
59+
.draw_get_protocol_self = (draw_get_protocol_self_fun)common_hal_vectorio_rectangle_get_draw_protocol,
60+
.draw_protocol_impl = &vectorio_vector_shape_draw_protocol_impl
61+
};
4262

4363
STATIC const mp_rom_map_elem_t vectorio_rectangle_locals_dict_table[] = {
64+
// Properties
65+
{ MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) },
66+
{ MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) },
67+
{ MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) },
4468
};
4569
STATIC MP_DEFINE_CONST_DICT(vectorio_rectangle_locals_dict, vectorio_rectangle_locals_dict_table);
4670

4771
const mp_obj_type_t vectorio_rectangle_type = {
4872
{ &mp_type_type },
4973
.name = MP_QSTR_Rectangle,
74+
.flags = MP_TYPE_FLAG_EXTENDED,
5075
.make_new = vectorio_rectangle_make_new,
5176
.locals_dict = (mp_obj_dict_t *)&vectorio_rectangle_locals_dict,
77+
MP_TYPE_EXTENDED_FIELDS(
78+
.protocol = &rectangle_draw_protocol,
79+
),
5280
};

shared-bindings/vectorio/Rectangle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ uint32_t common_hal_vectorio_rectangle_get_pixel(void *rectangle, int16_t x, int
1212

1313
void common_hal_vectorio_rectangle_get_area(void *rectangle, displayio_area_t *out_area);
1414

15+
mp_obj_t common_hal_vectorio_rectangle_get_draw_protocol(void *rectangle);
16+
1517
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_RECTANGLE_H

shared-bindings/vectorio/VectorShape.c

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -19,37 +19,16 @@
1919
#include "supervisor/shared/translate.h"
2020

2121

22-
//| class VectorShape:
23-
//| def __init__(self, shape: Union[Polygon, Rectangle, Circle], pixel_shader: Union[displayio.ColorConverter, displayio.Palette], x: int=0, y: int=0) -> None:
24-
//| """Binds a vector shape to a location and pixel shader. The shader can be a displayio.Palette(1); it will be asked to color pixel value 0.
25-
//|
26-
//| :param shape: The shape to draw.
27-
//| :param pixel_shader: The pixel shader that produces colors from values
28-
//| :param x: Initial x position of the center axis of the shape within the parent.
29-
//| :param y: Initial y position of the center axis of the shape within the parent."""
30-
//| ...
31-
//|
32-
STATIC mp_obj_t vectorio_vector_shape_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
33-
enum { ARG_shape, ARG_pixel_shader, ARG_x, ARG_y };
34-
static const mp_arg_t allowed_args[] = {
35-
{ MP_QSTR_shape, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
36-
{ MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
37-
{ MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
38-
{ MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
39-
};
40-
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
41-
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
42-
43-
mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj;
22+
// shape: The shape implementation to draw.
23+
// pixel_shader: The pixel shader that produces colors from values. The shader can be a displayio.Palette(1); it will be asked to color pixel value 0.
24+
// x: Initial x position of the center axis of the shape within the parent.
25+
// y: Initial y position of the center axis of the shape within the parent."""
26+
mp_obj_t vectorio_vector_shape_make_new(const mp_obj_t shape, const mp_obj_t pixel_shader, int16_t x, int16_t y) {
4427
if (!mp_obj_is_type(pixel_shader, &displayio_colorconverter_type) &&
4528
!mp_obj_is_type(pixel_shader, &displayio_palette_type)) {
4629
mp_raise_TypeError_varg(translate("unsupported %q type"), MP_QSTR_pixel_shader);
4730
}
4831

49-
int16_t x = args[ARG_x].u_int;
50-
int16_t y = args[ARG_y].u_int;
51-
52-
mp_obj_t shape = args[ARG_shape].u_obj;
5332
vectorio_ishape_t ishape;
5433
// Wire up shape functions
5534
if (mp_obj_is_type(shape, &vectorio_polygon_type)) {
@@ -92,18 +71,31 @@ STATIC mp_obj_t vectorio_vector_shape_make_new(const mp_obj_type_t *type, size_t
9271
return MP_OBJ_FROM_PTR(self);
9372
}
9473

74+
vectorio_draw_protocol_impl_t vectorio_vector_shape_draw_protocol_impl = {
75+
.draw_fill_area = (draw_fill_area_fun)vectorio_vector_shape_fill_area,
76+
.draw_get_dirty_area = (draw_get_dirty_area_fun)vectorio_vector_shape_get_dirty_area,
77+
.draw_update_transform = (draw_update_transform_fun)vectorio_vector_shape_update_transform,
78+
.draw_finish_refresh = (draw_finish_refresh_fun)vectorio_vector_shape_finish_refresh,
79+
.draw_get_refresh_areas = (draw_get_refresh_areas_fun)vectorio_vector_shape_get_refresh_areas,
80+
};
81+
9582

9683
//| x: int
9784
//| """X position of the center point of the shape in the parent."""
9885
//|
99-
STATIC mp_obj_t vectorio_vector_shape_obj_get_x(mp_obj_t self_in) {
100-
vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in);
86+
STATIC mp_obj_t vectorio_vector_shape_obj_get_x(mp_obj_t wrapper_shape) {
87+
// Relies on the fact that only vector_shape impl gets matched with a VectorShape.
88+
const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape);
89+
vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape));
90+
10191
return MP_OBJ_NEW_SMALL_INT(common_hal_vectorio_vector_shape_get_x(self));
10292
}
10393
MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_x_obj, vectorio_vector_shape_obj_get_x);
10494

105-
STATIC mp_obj_t vectorio_vector_shape_obj_set_x(mp_obj_t self_in, mp_obj_t x_obj) {
106-
vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in);
95+
STATIC mp_obj_t vectorio_vector_shape_obj_set_x(mp_obj_t wrapper_shape, mp_obj_t x_obj) {
96+
// Relies on the fact that only vector_shape impl gets matched with a VectorShape.
97+
const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape);
98+
vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape));
10799

108100
mp_int_t x = mp_obj_get_int(x_obj);
109101
common_hal_vectorio_vector_shape_set_x(self, x);
@@ -122,14 +114,19 @@ const mp_obj_property_t vectorio_vector_shape_x_obj = {
122114
//| y: int
123115
//| """Y position of the center point of the shape in the parent."""
124116
//|
125-
STATIC mp_obj_t vectorio_vector_shape_obj_get_y(mp_obj_t self_in) {
126-
vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in);
117+
STATIC mp_obj_t vectorio_vector_shape_obj_get_y(mp_obj_t wrapper_shape) {
118+
// Relies on the fact that only vector_shape impl gets matched with a VectorShape.
119+
const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape);
120+
vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape));
121+
127122
return MP_OBJ_NEW_SMALL_INT(common_hal_vectorio_vector_shape_get_y(self));
128123
}
129124
MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_y_obj, vectorio_vector_shape_obj_get_y);
130125

131-
STATIC mp_obj_t vectorio_vector_shape_obj_set_y(mp_obj_t self_in, mp_obj_t y_obj) {
132-
vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in);
126+
STATIC mp_obj_t vectorio_vector_shape_obj_set_y(mp_obj_t wrapper_shape, mp_obj_t y_obj) {
127+
// Relies on the fact that only vector_shape impl gets matched with a VectorShape.
128+
const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape);
129+
vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape));
133130

134131
mp_int_t y = mp_obj_get_int(y_obj);
135132
common_hal_vectorio_vector_shape_set_y(self, y);
@@ -148,14 +145,20 @@ const mp_obj_property_t vectorio_vector_shape_y_obj = {
148145
//| pixel_shader: Union[displayio.ColorConverter, displayio.Palette]
149146
//| """The pixel shader of the shape."""
150147
//|
151-
STATIC mp_obj_t vectorio_vector_shape_obj_get_pixel_shader(mp_obj_t self_in) {
152-
vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in);
148+
STATIC mp_obj_t vectorio_vector_shape_obj_get_pixel_shader(mp_obj_t wrapper_shape) {
149+
// Relies on the fact that only vector_shape impl gets matched with a VectorShape.
150+
const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape);
151+
vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape));
152+
153153
return common_hal_vectorio_vector_shape_get_pixel_shader(self);
154154
}
155155
MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_pixel_shader_obj, vectorio_vector_shape_obj_get_pixel_shader);
156156

157-
STATIC mp_obj_t vectorio_vector_shape_obj_set_pixel_shader(mp_obj_t self_in, mp_obj_t pixel_shader) {
158-
vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in);
157+
STATIC mp_obj_t vectorio_vector_shape_obj_set_pixel_shader(mp_obj_t wrapper_shape, mp_obj_t pixel_shader) {
158+
// Relies on the fact that only vector_shape impl gets matched with a VectorShape.
159+
const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape);
160+
vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape));
161+
159162
if (!mp_obj_is_type(pixel_shader, &displayio_palette_type) && !mp_obj_is_type(pixel_shader, &displayio_colorconverter_type)) {
160163
mp_raise_TypeError(translate("pixel_shader must be displayio.Palette or displayio.ColorConverter"));
161164
}
@@ -175,16 +178,11 @@ const mp_obj_property_t vectorio_vector_shape_pixel_shader_obj = {
175178

176179

177180
STATIC const mp_rom_map_elem_t vectorio_vector_shape_locals_dict_table[] = {
178-
// Properties
179-
{ MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) },
180-
{ MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) },
181-
{ MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) },
182181
};
183182
STATIC MP_DEFINE_CONST_DICT(vectorio_vector_shape_locals_dict, vectorio_vector_shape_locals_dict_table);
184183

185184
const mp_obj_type_t vectorio_vector_shape_type = {
186185
{ &mp_type_type },
187186
.name = MP_QSTR_VectorShape,
188-
.make_new = vectorio_vector_shape_make_new,
189187
.locals_dict = (mp_obj_dict_t *)&vectorio_vector_shape_locals_dict,
190188
};

0 commit comments

Comments
 (0)