@@ -72,6 +72,12 @@ static uint32_t min(uint32_t a, uint32_t b) {
7272 return a < b ? a : b ;
7373}
7474
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+
7581inline __attribute__((always_inline ))
7682static void area_transpose (displayio_area_t * to_transpose ) {
7783 int16_t swap = to_transpose -> y1 ;
@@ -124,21 +130,50 @@ static void _get_screen_area(vectorio_vector_shape_t *self, displayio_area_t *ou
124130 VECTORIO_SHAPE_DEBUG (" out:{(%5d,%5d), (%5d,%5d)}\n" , out_area -> x1 , out_area -> y1 , out_area -> x2 , out_area -> y2 );
125131}
126132
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 ;
127138
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+ // }
132167 }
133- self -> x = x ;
134168}
135169
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+ }
136174
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 );
142177 self -> y = y ;
143178}
144179
@@ -195,6 +230,17 @@ void common_hal_vectorio_vector_shape_construct(vectorio_vector_shape_t *self,
195230 _get_screen_area (self , & self -> current_area );
196231}
197232
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+
198244
199245mp_int_t common_hal_vectorio_vector_shape_get_x (vectorio_vector_shape_t * self ) {
200246 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 *
277323 common_hal_vectorio_vector_shape_set_dirty (self );
278324}
279325
280-
281326bool 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 ) {
282327 // Shape areas are relative to 0,0. This will allow rotation about a known axis.
283328 // 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
335380 }
336381 output_pixel .pixel = 0 ;
337382
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
339384 int16_t pixel_to_get_x ;
340385 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 );
374387
375388 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 );
376389 #ifdef VECTORIO_PERF
0 commit comments