Skip to content

Commit b5837b1

Browse files
committed
improve transpose and mirror
* add heuristic to avoid drawing area unnecessarily * fix Polygon.points * fix transpose * fix mirror x and y Known broken: Polygon with negative Y coordinates does not work right.
1 parent 6be952d commit b5837b1

File tree

3 files changed

+185
-96
lines changed

3 files changed

+185
-96
lines changed

shared-module/vectorio/Polygon.c

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111

1212
#define VECTORIO_POLYGON_DEBUG(...) (void)0
13-
// #define VECTORIO_POLYGON_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__)
13+
// #define VECTORIO_POLYGON_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__)
1414

1515

1616
// Converts a list of points tuples to a flat list of ints for speedier internal use.
@@ -30,27 +30,32 @@ static void _clobber_points_list(vectorio_polygon_t *self, mp_obj_t points_tuple
3030
VECTORIO_POLYGON_DEBUG("free(%d), ", sizeof(self->points_list));
3131
gc_free(self->points_list);
3232
}
33-
self->points_list = gc_alloc(2 * len * sizeof(int), false, false);
34-
VECTORIO_POLYGON_DEBUG("alloc(%p, %d)", self->points_list, 2 * len * sizeof(int));
33+
self->points_list = gc_alloc(2 * len * sizeof(uint16_t), false, false);
34+
VECTORIO_POLYGON_DEBUG("alloc(%p, %d)", self->points_list, 2 * len * sizeof(uint16_t));
3535
}
3636
self->len = 2 * len;
3737

38-
for (size_t i = 0; i < len; ++i) {
38+
for (uint16_t i = 0; i < len; ++i) {
3939
size_t tuple_len = 0;
4040
mp_obj_t *tuple_items;
4141
mp_obj_tuple_get(items[i], &tuple_len, &tuple_items);
4242

4343
if (tuple_len != 2) {
4444
mp_raise_ValueError_varg(translate("%q must be a tuple of length 2"), MP_QSTR_point);
4545
}
46-
if (!mp_obj_get_int_maybe(tuple_items[ 0 ], &self->points_list[2 * i ])
47-
|| !mp_obj_get_int_maybe(tuple_items[ 1 ], &self->points_list[2 * i + 1])
46+
mp_int_t x;
47+
mp_int_t y;
48+
if (!mp_obj_get_int_maybe(tuple_items[ 0 ], &x)
49+
|| !mp_obj_get_int_maybe(tuple_items[ 1 ], &y)
50+
|| x < SHRT_MIN || x > SHRT_MAX || y < SHRT_MIN || y > SHRT_MAX
4851
) {
49-
self->len = 0;
5052
gc_free(self->points_list);
5153
self->points_list = NULL;
5254
mp_raise_ValueError_varg(translate("unsupported %q type"), MP_QSTR_point);
55+
self->len = 0;
5356
}
57+
self->points_list[2 * i ] = (int16_t)x;
58+
self->points_list[2 * i + 1] = (int16_t)y;
5459
}
5560
}
5661

@@ -68,16 +73,23 @@ void common_hal_vectorio_polygon_construct(vectorio_polygon_t *self, mp_obj_t po
6873

6974
mp_obj_t common_hal_vectorio_polygon_get_points(vectorio_polygon_t *self) {
7075
VECTORIO_POLYGON_DEBUG("%p common_hal_vectorio_polygon_get_points {len: %d, points_list: %p}\n", self, self->len, self->points_list);
71-
mp_obj_t list = mp_obj_new_list(self->len / 2, NULL);
76+
mp_obj_list_t *list = MP_OBJ_TO_PTR(mp_obj_new_list(0, NULL));
77+
78+
VECTORIO_POLYGON_DEBUG(" >points\n");
79+
for (uint16_t i = 0; i < self->len; i += 2) {
80+
VECTORIO_POLYGON_DEBUG(" (%4d, %4d)\n", self->points_list[i], self->points_list[i + 1]);
81+
82+
mp_obj_tuple_t *pair = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
83+
pair->items[0] = mp_obj_new_int((mp_int_t) self->points_list[i ]);
84+
pair->items[1] = mp_obj_new_int((mp_int_t) self->points_list[i + 1]);
7285

73-
for (size_t i = 0; i < self->len; i += 2) {
74-
mp_obj_t tuple[] = { mp_obj_new_int(self->points_list[i]), mp_obj_new_int(self->points_list[i + 1]) };
7586
mp_obj_list_append(
7687
list,
77-
mp_obj_new_tuple(2, tuple)
88+
pair
7889
);
7990
}
80-
return list;
91+
VECTORIO_POLYGON_DEBUG(" <points\n");
92+
return MP_OBJ_FROM_PTR(list);
8193
}
8294
void common_hal_vectorio_polygon_set_points(vectorio_polygon_t *self, mp_obj_t points_list) {
8395
VECTORIO_POLYGON_DEBUG("%p common_hal_vectorio_polygon_set_points: ", self);
@@ -98,25 +110,30 @@ void common_hal_vectorio_polygon_set_on_dirty(vectorio_polygon_t *self, vectorio
98110

99111
void common_hal_vectorio_polygon_get_area(void *polygon, displayio_area_t *area) {
100112
vectorio_polygon_t *self = polygon;
113+
VECTORIO_POLYGON_DEBUG("%p common_hal_vectorio_polygon_get_area\n");
101114

102115
area->x1 = SHRT_MAX;
103116
area->y1 = SHRT_MAX;
104117
area->x2 = SHRT_MIN;
105118
area->y2 = SHRT_MIN;
106-
for (size_t i = 0; i < self->len; ++i) {
107-
int x = self->points_list[i];
119+
for (uint16_t i = 0; i < self->len; ++i) {
120+
int16_t x = self->points_list[i];
108121
++i;
109-
int y = self->points_list[i];
122+
int16_t y = self->points_list[i];
110123
if (x < area->x1) {
124+
VECTORIO_POLYGON_DEBUG(" x1: %d\n", x);
111125
area->x1 = x;
112126
}
113127
if (y < area->y1) {
128+
VECTORIO_POLYGON_DEBUG(" y1: %d\n", y);
114129
area->y1 = y;
115130
}
116131
if (x > area->x2) {
132+
VECTORIO_POLYGON_DEBUG(" x2: %d\n", x);
117133
area->x2 = x;
118134
}
119135
if (y > area->y2) {
136+
VECTORIO_POLYGON_DEBUG(" y2: %d\n", y);
120137
area->y2 = y;
121138
}
122139
}
@@ -126,7 +143,7 @@ void common_hal_vectorio_polygon_get_area(void *polygon, displayio_area_t *area)
126143
// <0 if the point is to the left of the line vector
127144
// 0 if the point is on the line
128145
// >0 if the point is to the right of the line vector
129-
__attribute__((always_inline)) static inline int line_side(mp_int_t x1, mp_int_t y1, mp_int_t x2, mp_int_t y2, int16_t px, int16_t py) {
146+
__attribute__((always_inline)) static inline int line_side(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t px, int16_t py) {
130147
return (px - x1) * (y2 - y1)
131148
- (py - y1) * (x2 - x1);
132149
}
@@ -140,14 +157,14 @@ uint32_t common_hal_vectorio_polygon_get_pixel(void *obj, int16_t x, int16_t y)
140157
return 0;
141158
}
142159

143-
int winding_number = 0;
144-
int x1 = self->points_list[0];
145-
int y1 = self->points_list[1];
146-
for (size_t i = 2; i <= self->len + 1; ++i) {
160+
int16_t winding_number = 0;
161+
int16_t x1 = self->points_list[0];
162+
int16_t y1 = self->points_list[1];
163+
for (uint16_t i = 2; i <= self->len + 1; ++i) {
147164
VECTORIO_POLYGON_DEBUG(" {(%3d, %3d),", x1, y1);
148-
int x2 = self->points_list[i % self->len];
165+
int16_t x2 = self->points_list[i % self->len];
149166
++i;
150-
int y2 = self->points_list[i % self->len];
167+
int16_t y2 = self->points_list[i % self->len];
151168
VECTORIO_POLYGON_DEBUG(" (%3d, %3d)}\n", x2, y2);
152169
if (y1 <= y) {
153170
if (y2 > y && line_side(x1, y1, x2, y2, x, y) < 0) {

shared-module/vectorio/Polygon.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
typedef struct {
1010
mp_obj_base_t base;
1111
// An int array[ x, y, ... ]
12-
int *points_list;
13-
size_t len;
12+
int16_t *points_list;
13+
uint16_t len;
1414
vectorio_event_t on_dirty;
1515
mp_obj_t draw_protocol_instance;
1616
} vectorio_polygon_t;

0 commit comments

Comments
 (0)