@@ -72,6 +72,12 @@ static uint32_t min(uint32_t a, uint32_t b) {
72
72
return a < b ? a : b ;
73
73
}
74
74
75
+ static void short_bound_check (mp_int_t i , qstr name ) {
76
+ if (i < SHRT_MIN || i > SHRT_MAX ) {
77
+ mp_raise_ValueError_varg (translate ("%q must be between %d and %d" ), name , SHRT_MIN , SHRT_MAX );
78
+ }
79
+ }
80
+
75
81
inline __attribute__((always_inline ))
76
82
static void area_transpose (displayio_area_t * to_transpose ) {
77
83
int16_t swap = to_transpose -> y1 ;
@@ -124,21 +130,50 @@ static void _get_screen_area(vectorio_vector_shape_t *self, displayio_area_t *ou
124
130
VECTORIO_SHAPE_DEBUG (" out:{(%5d,%5d), (%5d,%5d)}\n" , out_area -> x1 , out_area -> y1 , out_area -> x2 , out_area -> y2 );
125
131
}
126
132
133
+ // Get the target pixel based on the shape's coordinate space
134
+ static void screen_to_shape_coordinates (vectorio_vector_shape_t * self , uint16_t x , uint16_t y , int16_t * out_shape_x , int16_t * out_shape_y ) {
135
+ if (self -> absolute_transform -> transpose_xy ) {
136
+ * out_shape_x = y - self -> absolute_transform -> y - self -> absolute_transform -> dy * self -> x ;
137
+ * out_shape_y = x - self -> absolute_transform -> x - self -> absolute_transform -> dx * self -> y ;
127
138
128
- STATIC
129
- void check_bounds_and_set_x (vectorio_vector_shape_t * self , mp_int_t x ) {
130
- if (x < SHRT_MIN || x > SHRT_MAX ) {
131
- mp_raise_ValueError_varg (translate ("%q must be between %d and %d" ), MP_QSTR_x , SHRT_MIN , SHRT_MAX );
139
+ VECTORIO_SHAPE_PIXEL_DEBUG (" a(%3d, %3d)" , * out_shape_x , * out_shape_y );
140
+ if (self -> absolute_transform -> dx < 1 ) {
141
+ * out_shape_y *= -1 ;
142
+ }
143
+ if (self -> absolute_transform -> dy < 1 ) {
144
+ * out_shape_x *= -1 ;
145
+ }
146
+ VECTORIO_SHAPE_PIXEL_DEBUG (" b(%3d, %3d)" , * out_shape_x , * out_shape_y );
147
+ } else {
148
+ * out_shape_x = x - self -> absolute_transform -> x - self -> absolute_transform -> dx * self -> x ;
149
+ * out_shape_y = y - self -> absolute_transform -> y - self -> absolute_transform -> dy * self -> y ;
150
+
151
+ VECTORIO_SHAPE_PIXEL_DEBUG (" a(%3d, %3d)" , * out_shape_x , * out_shape_y );
152
+ if (self -> absolute_transform -> dx < 1 ) {
153
+ * out_shape_x *= -1 ;
154
+ }
155
+ if (self -> absolute_transform -> dy < 1 ) {
156
+ * out_shape_y *= -1 ;
157
+ }
158
+ VECTORIO_SHAPE_PIXEL_DEBUG (" b(%3d, %3d)" , * out_shape_x , * out_shape_y );
159
+
160
+ // It's mirrored via dx. Maybe we need to add support for also separately mirroring?
161
+ // if (self->absolute_transform->mirror_x) {
162
+ // pixel_to_get_x = (shape_area.x2 - shape_area.x1) - (pixel_to_get_x - shape_area.x1) + shape_area.x1 - 1;
163
+ // }
164
+ // if (self->absolute_transform->mirror_y) {
165
+ // pixel_to_get_y = (shape_area.y2 - shape_area.y1) - (pixel_to_get_y - shape_area.y1) + +shape_area.y1 - 1;
166
+ // }
132
167
}
133
- self -> x = x ;
134
168
}
135
169
170
+ static void check_bounds_and_set_x (vectorio_vector_shape_t * self , mp_int_t x ) {
171
+ short_bound_check (x , MP_QSTR_x );
172
+ self -> x = x ;
173
+ }
136
174
137
- STATIC
138
- void check_bounds_and_set_y (vectorio_vector_shape_t * self , mp_int_t y ) {
139
- if (y < SHRT_MIN || y > SHRT_MAX ) {
140
- mp_raise_ValueError_varg (translate ("%q must be between %d and %d" ), MP_QSTR_y , SHRT_MIN , SHRT_MAX );
141
- }
175
+ static void check_bounds_and_set_y (vectorio_vector_shape_t * self , mp_int_t y ) {
176
+ short_bound_check (y , MP_QSTR_y );
142
177
self -> y = y ;
143
178
}
144
179
@@ -195,6 +230,17 @@ void common_hal_vectorio_vector_shape_construct(vectorio_vector_shape_t *self,
195
230
_get_screen_area (self , & self -> current_area );
196
231
}
197
232
233
+ bool common_hal_vectorio_vector_shape_contains (vectorio_vector_shape_t * self , mp_int_t x , mp_int_t y ) {
234
+ VECTORIO_SHAPE_DEBUG ("%p contains(%d, %d)" , self );
235
+ short_bound_check (x , MP_QSTR_x );
236
+ short_bound_check (y , MP_QSTR_y );
237
+ int16_t shape_x ;
238
+ int16_t shape_y ;
239
+ screen_to_shape_coordinates (self , x , y , & shape_x , & shape_y );
240
+ bool shape_contains_coordinates = 0 != self -> ishape .get_pixel (self -> ishape .shape , shape_x , shape_y );
241
+ return shape_contains_coordinates ;
242
+ }
243
+
198
244
199
245
mp_int_t common_hal_vectorio_vector_shape_get_x (vectorio_vector_shape_t * self ) {
200
246
VECTORIO_SHAPE_DEBUG ("%p get_x\n" , self );
@@ -277,7 +323,6 @@ void common_hal_vectorio_vector_shape_set_pixel_shader(vectorio_vector_shape_t *
277
323
common_hal_vectorio_vector_shape_set_dirty (self );
278
324
}
279
325
280
-
281
326
bool vectorio_vector_shape_fill_area (vectorio_vector_shape_t * self , const _displayio_colorspace_t * colorspace , const displayio_area_t * area , uint32_t * mask , uint32_t * buffer ) {
282
327
// Shape areas are relative to 0,0. This will allow rotation about a known axis.
283
328
// The consequence is that the area reported by the shape itself is _relative_ to 0,0.
@@ -335,42 +380,10 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ
335
380
}
336
381
output_pixel .pixel = 0 ;
337
382
338
- // Get the target pixel based on the shape's coordinate space
383
+ // Cast input screen coordinates to shape coordinates to pick the pixel to draw
339
384
int16_t pixel_to_get_x ;
340
385
int16_t pixel_to_get_y ;
341
- if (self -> absolute_transform -> transpose_xy ) {
342
- pixel_to_get_x = input_pixel .y - self -> absolute_transform -> y - self -> absolute_transform -> dy * self -> x ;
343
- pixel_to_get_y = input_pixel .x - self -> absolute_transform -> x - self -> absolute_transform -> dx * self -> y ;
344
-
345
- VECTORIO_SHAPE_PIXEL_DEBUG (" a(%3d, %3d)" , pixel_to_get_x , pixel_to_get_y );
346
- if (self -> absolute_transform -> dx < 1 ) {
347
- pixel_to_get_y *= -1 ;
348
- }
349
- if (self -> absolute_transform -> dy < 1 ) {
350
- pixel_to_get_x *= -1 ;
351
- }
352
- VECTORIO_SHAPE_PIXEL_DEBUG (" b(%3d, %3d)" , pixel_to_get_x , pixel_to_get_y );
353
- } else {
354
- pixel_to_get_x = input_pixel .x - self -> absolute_transform -> x - self -> absolute_transform -> dx * self -> x ;
355
- pixel_to_get_y = input_pixel .y - self -> absolute_transform -> y - self -> absolute_transform -> dy * self -> y ;
356
-
357
- VECTORIO_SHAPE_PIXEL_DEBUG (" a(%3d, %3d)" , pixel_to_get_x , pixel_to_get_y );
358
- if (self -> absolute_transform -> dx < 1 ) {
359
- pixel_to_get_x *= -1 ;
360
- }
361
- if (self -> absolute_transform -> dy < 1 ) {
362
- pixel_to_get_y *= -1 ;
363
- }
364
- VECTORIO_SHAPE_PIXEL_DEBUG (" b(%3d, %3d)" , pixel_to_get_x , pixel_to_get_y );
365
-
366
- // It's mirrored via dx. Maybe we need to add support for also separately mirroring?
367
- // if (self->absolute_transform->mirror_x) {
368
- // pixel_to_get_x = (shape_area.x2 - shape_area.x1) - (pixel_to_get_x - shape_area.x1) + shape_area.x1 - 1;
369
- // }
370
- // if (self->absolute_transform->mirror_y) {
371
- // pixel_to_get_y = (shape_area.y2 - shape_area.y1) - (pixel_to_get_y - shape_area.y1) + +shape_area.y1 - 1;
372
- // }
373
- }
386
+ screen_to_shape_coordinates (self , input_pixel .x , input_pixel .y , & pixel_to_get_x , & pixel_to_get_y );
374
387
375
388
VECTORIO_SHAPE_PIXEL_DEBUG (" get_pixel %p (%3d, %3d) -> ( %3d, %3d )" , self -> ishape .shape , input_pixel .x , input_pixel .y , pixel_to_get_x , pixel_to_get_y );
376
389
#ifdef VECTORIO_PERF
0 commit comments