@@ -38,20 +38,20 @@ void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t widt
3838 self -> width = width ;
3939 if (self -> mirror_x ) {
4040 width /= 2 ;
41- width += self -> width % 2 - 1 ;
41+ width += self -> width % 2 ;
4242 }
4343 self -> half_width = width ;
4444
4545 self -> height = height ;
4646 if (self -> mirror_y ) {
4747 height /= 2 ;
48- height += self -> height % 2 - 1 ;
48+ height += self -> height % 2 ;
4949 }
5050 self -> half_height = height ;
5151
5252 self -> data = m_malloc (height * sizeof (uint32_t ), false);
5353
54- for (uint16_t i = 0 ; i <= height ; i ++ ) {
54+ for (uint16_t i = 0 ; i < height ; i ++ ) {
5555 self -> data [2 * i ] = 0 ;
5656 self -> data [2 * i + 1 ] = width ;
5757 }
@@ -63,69 +63,63 @@ void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t widt
6363}
6464
6565void common_hal_displayio_shape_set_boundary (displayio_shape_t * self , uint16_t y , uint16_t start_x , uint16_t end_x ) {
66- if (y < 0 || y >= self -> height || (self -> mirror_y && y > self -> half_height )) {
66+ if (y < 0 || y >= self -> height || (self -> mirror_y && y >= self -> half_height )) {
6767 mp_raise_ValueError (translate ("y value out of bounds" ));
6868 }
69- if (start_x < 0 || start_x > self -> width || end_x < 0 || end_x > self -> width ) {
69+ if (start_x < 0 || start_x >= self -> width || end_x < 0 || end_x >= self -> width ) {
7070 mp_raise_ValueError (translate ("x value out of bounds" ));
7171 }
72- uint16_t half_width = self -> width / 2 - 1 + self -> width % 2 ;
73- if (self -> mirror_x && (start_x > half_width || end_x > half_width )) {
74- mp_raise_ValueError_varg (translate ("Maximum x value when mirrored is %d" ), half_width );
72+ if (self -> mirror_x && (start_x >= self -> half_width || end_x >= self -> half_width )) {
73+ mp_raise_ValueError_varg (translate ("Maximum x value when mirrored is %d" ), self -> half_width );
7574 }
7675
77- uint16_t lower_x , upper_x ;
76+ uint16_t lower_x , upper_x , lower_y , upper_y ;
7877
79- // find x-boundaries for updating based on current data and start_x, end_x
78+ // find x-boundaries for updating based on current data and start_x, end_x, and mirror_x
8079 lower_x = MIN (start_x , self -> data [2 * y ]);
8180
8281 if (self -> mirror_x ) {
83- upper_x = self -> width - lower_x ;
82+ upper_x = self -> width - lower_x + 1 ; // dirty rectangles are treated with max value exclusive
8483 } else {
85- upper_x = 1 + MAX (end_x , self -> data [2 * y + 1 ]);
84+ upper_x = MAX (end_x , self -> data [2 * y + 1 ]) + 1 ; // dirty rectangles are treated with max value exclusive
8685 }
8786
88- self -> data [2 * y ] = start_x ;
87+ // find y-boundaries based on y and mirror_y
88+ lower_y = y ;
89+
90+ if (self -> mirror_y ) {
91+ upper_y = self -> height - lower_y + 1 ; // dirty rectangles are treated with max value exclusive
92+ } else {
93+ upper_y = y + 1 ; // dirty rectangles are treated with max value exclusive
94+ }
95+
96+ self -> data [2 * y ] = start_x ; // update the data array with the new boundaries
8997 self -> data [2 * y + 1 ] = end_x ;
9098
9199 if (self -> dirty_area .x1 == self -> dirty_area .x2 ) { // Dirty region is empty
92- self -> dirty_area .x1 = lower_x ;
93- self -> dirty_area .x2 = upper_x ;
94- self -> dirty_area .y1 = y ;
95- if (self -> mirror_y ) {
96- self -> dirty_area .y2 = self -> height - y ;
97- } else {
98- self -> dirty_area .y2 = y + 1 ;
99- }
100- } else { // Dirty region is not empty
100+ self -> dirty_area .x1 = lower_x ;
101+ self -> dirty_area .x2 = upper_x ;
102+ self -> dirty_area .y1 = lower_y ;
103+ self -> dirty_area .y2 = upper_y ;
101104
105+ } else { // Dirty region is not empty
102106 self -> dirty_area .x1 = MIN (lower_x , self -> dirty_area .x1 );
103107 self -> dirty_area .x2 = MAX (upper_x , self -> dirty_area .x2 );
104108
105- if (y < self -> dirty_area .y1 ) {
106- self -> dirty_area .y1 = y ;
107- if (self -> mirror_y ) { // if y is mirrored and the lower y was updated, the upper y must be updated too
108- self -> dirty_area .y2 = self -> height - y ;
109- }
110- }
111- else {
112- if ( !self -> mirror_y && (y >= self -> dirty_area .y2 ) ) { // y is not mirrored
113- self -> dirty_area .y2 = y + 1 ;
114- }
115- }
109+ self -> dirty_area .y1 = MIN (lower_y , self -> dirty_area .y1 );
110+ self -> dirty_area .y2 = MAX (upper_y , self -> dirty_area .y2 );
116111 }
117-
118112}
119113
120114uint32_t common_hal_displayio_shape_get_pixel (void * obj , int16_t x , int16_t y ) {
121115 displayio_shape_t * self = obj ;
122116 if (x >= self -> width || x < 0 || y >= self -> height || y < 0 ) {
123117 return 0 ;
124118 }
125- if (self -> mirror_x && x > self -> half_width ) {
126- x = self -> width - 1 - x ;
119+ if (self -> mirror_x && x >= self -> half_width ) {
120+ x = self -> width - x - 1 ;
127121 }
128- if (self -> mirror_y && y > self -> half_height ) {
122+ if (self -> mirror_y && y >= self -> half_height ) {
129123 y = self -> height - y - 1 ;
130124 }
131125 uint16_t start_x = self -> data [2 * y ];
0 commit comments