Skip to content

Commit 37e85ae

Browse files
committed
Fix off-by-one error, simplify the logic, add comments
1 parent d600759 commit 37e85ae

File tree

1 file changed

+31
-37
lines changed

1 file changed

+31
-37
lines changed

shared-module/displayio/Shape.c

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -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

6565
void 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

120114
uint32_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

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy