29
29
#include <string.h>
30
30
31
31
#include "py/runtime.h"
32
+ #include "py/misc.h"
32
33
33
34
void common_hal_displayio_shape_construct (displayio_shape_t * self , uint32_t width ,
34
35
uint32_t height , bool mirror_x , bool mirror_y ) {
@@ -37,48 +38,88 @@ void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t widt
37
38
self -> width = width ;
38
39
if (self -> mirror_x ) {
39
40
width /= 2 ;
40
- width += self -> width % 2 - 1 ;
41
+ width += self -> width % 2 ;
41
42
}
42
43
self -> half_width = width ;
43
44
44
45
self -> height = height ;
45
46
if (self -> mirror_y ) {
46
47
height /= 2 ;
47
- height += self -> height % 2 - 1 ;
48
+ height += self -> height % 2 ;
48
49
}
49
50
self -> half_height = height ;
50
51
51
52
self -> data = m_malloc (height * sizeof (uint32_t ), false);
52
- for (uint16_t i = 0 ; i <= height ; i ++ ) {
53
+
54
+ for (uint16_t i = 0 ; i < height ; i ++ ) {
53
55
self -> data [2 * i ] = 0 ;
54
56
self -> data [2 * i + 1 ] = width ;
55
57
}
58
+
59
+ self -> dirty_area .x1 = 0 ;
60
+ self -> dirty_area .x2 = width ;
61
+ self -> dirty_area .y1 = 0 ;
62
+ self -> dirty_area .y2 = height ;
56
63
}
57
64
58
65
void common_hal_displayio_shape_set_boundary (displayio_shape_t * self , uint16_t y , uint16_t start_x , uint16_t end_x ) {
59
- 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 )) {
60
67
mp_raise_ValueError (translate ("y value out of bounds" ));
61
68
}
62
- 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 ) {
63
70
mp_raise_ValueError (translate ("x value out of bounds" ));
64
71
}
65
- uint16_t half_width = self -> width / 2 - 1 + self -> width % 2 ;
66
- if (self -> mirror_x && (start_x > half_width || end_x > half_width )) {
67
- 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 );
74
+ }
75
+
76
+ uint16_t lower_x , upper_x , lower_y , upper_y ;
77
+
78
+ // find x-boundaries for updating based on current data and start_x, end_x, and mirror_x
79
+ lower_x = MIN (start_x , self -> data [2 * y ]);
80
+
81
+ if (self -> mirror_x ) {
82
+ upper_x = self -> width - lower_x + 1 ; // dirty rectangles are treated with max value exclusive
83
+ } else {
84
+ upper_x = MAX (end_x , self -> data [2 * y + 1 ]) + 1 ; // dirty rectangles are treated with max value exclusive
85
+ }
86
+
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
68
94
}
69
- self -> data [2 * y ] = start_x ;
95
+
96
+ self -> data [2 * y ] = start_x ; // update the data array with the new boundaries
70
97
self -> data [2 * y + 1 ] = end_x ;
98
+
99
+ if (self -> dirty_area .x1 == self -> dirty_area .x2 ) { // Dirty region is 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 ;
104
+
105
+ } else { // Dirty region is not empty
106
+ self -> dirty_area .x1 = MIN (lower_x , self -> dirty_area .x1 );
107
+ self -> dirty_area .x2 = MAX (upper_x , self -> dirty_area .x2 );
108
+
109
+ self -> dirty_area .y1 = MIN (lower_y , self -> dirty_area .y1 );
110
+ self -> dirty_area .y2 = MAX (upper_y , self -> dirty_area .y2 );
111
+ }
71
112
}
72
113
73
114
uint32_t common_hal_displayio_shape_get_pixel (void * obj , int16_t x , int16_t y ) {
74
115
displayio_shape_t * self = obj ;
75
116
if (x >= self -> width || x < 0 || y >= self -> height || y < 0 ) {
76
117
return 0 ;
77
118
}
78
- if (self -> mirror_x && x > self -> half_width ) {
79
- x = self -> width - 1 - x ;
119
+ if (self -> mirror_x && x >= self -> half_width ) {
120
+ x = self -> width - x - 1 ;
80
121
}
81
- if (self -> mirror_y && y > self -> half_height ) {
122
+ if (self -> mirror_y && y >= self -> half_height ) {
82
123
y = self -> height - y - 1 ;
83
124
}
84
125
uint16_t start_x = self -> data [2 * y ];
@@ -88,3 +129,16 @@ uint32_t common_hal_displayio_shape_get_pixel(void *obj, int16_t x, int16_t y) {
88
129
}
89
130
return 1 ;
90
131
}
132
+
133
+ displayio_area_t * displayio_shape_get_refresh_areas (displayio_shape_t * self , displayio_area_t * tail ) {
134
+ if (self -> dirty_area .x1 == self -> dirty_area .x2 ) {
135
+ return tail ;
136
+ }
137
+ self -> dirty_area .next = tail ;
138
+ return & self -> dirty_area ;
139
+ }
140
+
141
+ void displayio_shape_finish_refresh (displayio_shape_t * self ) {
142
+ self -> dirty_area .x1 = 0 ;
143
+ self -> dirty_area .x2 = 0 ;
144
+ }
0 commit comments