@@ -147,6 +147,14 @@ STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const di
147147 return true;
148148 }
149149 uint16_t subrectangles = 1 ;
150+
151+ // If pixels are packed by row then rows are on byte boundaries
152+ if (self -> core .colorspace .depth < 8 && self -> core .colorspace .pixels_in_byte_share_row ) {
153+ int div = 8 / self -> core .colorspace .depth ;
154+ clipped .x1 = (clipped .x1 / div ) * div ;
155+ clipped .x2 = ((clipped .x2 + div - 1 ) / div ) * div ;
156+ }
157+
150158 uint16_t rows_per_buffer = displayio_area_height (& clipped );
151159 uint8_t pixels_per_word = (sizeof (uint32_t ) * 8 ) / self -> core .colorspace .depth ;
152160 uint16_t pixels_per_buffer = displayio_area_size (& clipped );
@@ -187,6 +195,7 @@ STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const di
187195 .x2 = clipped .x2 ,
188196 .y2 = clipped .y1 + rows_per_buffer * (j + 1 )
189197 };
198+
190199 if (remaining_rows < rows_per_buffer ) {
191200 subrectangle .y2 = subrectangle .y1 + remaining_rows ;
192201 }
@@ -197,12 +206,15 @@ STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const di
197206
198207 displayio_display_core_fill_area (& self -> core , & subrectangle , mask , buffer );
199208
200- // COULDDO: this arithmetic only supports multiple-of-8 bpp
201- uint8_t * dest = self -> bufinfo .buf + (subrectangle .y1 * self -> core .width + subrectangle .x1 ) * (self -> core .colorspace .depth / 8 );
209+ uint8_t * buf = (uint8_t * )self -> bufinfo .buf , * endbuf = buf + self -> bufinfo .len ;
210+ (void )endbuf ; // Hint to compiler that endbuf is "used" even if NDEBUG
211+
212+ uint8_t * dest = self -> bufinfo .buf + (subrectangle .y1 * self -> core .width + subrectangle .x1 ) * self -> core .colorspace .depth / 8 ;
202213 uint8_t * src = (uint8_t * )buffer ;
203- size_t rowsize = (subrectangle .x2 - subrectangle .x1 ) * ( self -> core .colorspace .depth / 8 ) ;
204- size_t rowstride = self -> core .width * ( self -> core .colorspace .depth /8 ) ;
214+ size_t rowsize = (subrectangle .x2 - subrectangle .x1 ) * self -> core .colorspace .depth / 8 ;
215+ size_t rowstride = self -> core .width * self -> core .colorspace .depth /8 ;
205216 for (uint16_t i = subrectangle .y1 ; i < subrectangle .y2 ; i ++ ) {
217+ assert (dest >= buf && dest < endbuf && dest + rowsize <= endbuf );
206218 memcpy (dest , src , rowsize );
207219 dest += rowstride ;
208220 src += rowsize ;
0 commit comments