@@ -113,6 +113,21 @@ static inline uint32_t getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
113113 return formats [fb -> format ].getpixel (fb , x , y );
114114}
115115
116+ STATIC void fill_rect (const mp_obj_framebuf_t * fb , int x , int y , int w , int h , uint32_t col ) {
117+ if (x + w <= 0 || y + h <= 0 || y >= fb -> height || x >= fb -> width ) {
118+ // No operation needed.
119+ return ;
120+ }
121+
122+ // clip to the framebuffer
123+ int xend = MIN (fb -> width , x + w );
124+ int yend = MIN (fb -> height , y + h );
125+ x = MAX (x , 0 );
126+ y = MAX (y , 0 );
127+
128+ formats [fb -> format ].fill_rect (fb , x , y , xend - x , yend - y , col );
129+ }
130+
116131STATIC mp_obj_t framebuf_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * args ) {
117132 mp_arg_check_num (n_args , n_kw , 4 , 5 , false);
118133
@@ -162,18 +177,7 @@ STATIC mp_obj_t framebuf_fill_rect(size_t n_args, const mp_obj_t *args) {
162177 mp_int_t height = mp_obj_get_int (args [4 ]);
163178 mp_int_t color = mp_obj_get_int (args [5 ]);
164179
165- if (x + width <= 0 || y + height <= 0 || y >= self -> height || x >= self -> width ) {
166- // No operation needed.
167- return mp_const_none ;
168- }
169-
170- // clip to the framebuffer
171- int xend = MIN (self -> width , x + width );
172- int yend = MIN (self -> height , y + height );
173- x = MAX (MIN (x , self -> width ), 0 );
174- y = MAX (MIN (y , self -> height ), 0 );
175-
176- formats [self -> format ].fill_rect (self , x , y , xend - x , yend - y , color );
180+ fill_rect (self , x , y , width , height , color );
177181
178182 return mp_const_none ;
179183}
@@ -196,6 +200,115 @@ STATIC mp_obj_t framebuf_pixel(size_t n_args, const mp_obj_t *args) {
196200}
197201STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (framebuf_pixel_obj , 3 , 4 , framebuf_pixel );
198202
203+ STATIC mp_obj_t framebuf_hline (size_t n_args , const mp_obj_t * args ) {
204+ (void )n_args ;
205+
206+ mp_obj_framebuf_t * self = MP_OBJ_TO_PTR (args [0 ]);
207+ mp_int_t x = mp_obj_get_int (args [1 ]);
208+ mp_int_t y = mp_obj_get_int (args [2 ]);
209+ mp_int_t w = mp_obj_get_int (args [3 ]);
210+ mp_int_t col = mp_obj_get_int (args [4 ]);
211+
212+ fill_rect (self , x , y , w , 1 , col );
213+
214+ return mp_const_none ;
215+ }
216+ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (framebuf_hline_obj , 5 , 5 , framebuf_hline );
217+
218+ STATIC mp_obj_t framebuf_vline (size_t n_args , const mp_obj_t * args ) {
219+ (void )n_args ;
220+
221+ mp_obj_framebuf_t * self = MP_OBJ_TO_PTR (args [0 ]);
222+ mp_int_t x = mp_obj_get_int (args [1 ]);
223+ mp_int_t y = mp_obj_get_int (args [2 ]);
224+ mp_int_t h = mp_obj_get_int (args [3 ]);
225+ mp_int_t col = mp_obj_get_int (args [4 ]);
226+
227+ fill_rect (self , x , y , 1 , h , col );
228+
229+ return mp_const_none ;
230+ }
231+ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (framebuf_vline_obj , 5 , 5 , framebuf_vline );
232+
233+ STATIC mp_obj_t framebuf_rect (size_t n_args , const mp_obj_t * args ) {
234+ (void )n_args ;
235+
236+ mp_obj_framebuf_t * self = MP_OBJ_TO_PTR (args [0 ]);
237+ mp_int_t x = mp_obj_get_int (args [1 ]);
238+ mp_int_t y = mp_obj_get_int (args [2 ]);
239+ mp_int_t w = mp_obj_get_int (args [3 ]);
240+ mp_int_t h = mp_obj_get_int (args [4 ]);
241+ mp_int_t col = mp_obj_get_int (args [5 ]);
242+
243+ fill_rect (self , x , y , w , 1 , col );
244+ fill_rect (self , x , y + h - 1 , w , 1 , col );
245+ fill_rect (self , x , y , 1 , h , col );
246+ fill_rect (self , x + w - 1 , y , 1 , h , col );
247+
248+ return mp_const_none ;
249+ }
250+ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (framebuf_rect_obj , 6 , 6 , framebuf_rect );
251+
252+ STATIC mp_obj_t framebuf_line (size_t n_args , const mp_obj_t * args ) {
253+ (void )n_args ;
254+
255+ mp_obj_framebuf_t * self = MP_OBJ_TO_PTR (args [0 ]);
256+ mp_int_t x1 = mp_obj_get_int (args [1 ]);
257+ mp_int_t y1 = mp_obj_get_int (args [2 ]);
258+ mp_int_t x2 = mp_obj_get_int (args [3 ]);
259+ mp_int_t y2 = mp_obj_get_int (args [4 ]);
260+ mp_int_t col = mp_obj_get_int (args [5 ]);
261+
262+ mp_int_t dx = x2 - x1 ;
263+ mp_int_t sx ;
264+ if (dx > 0 ) {
265+ sx = 1 ;
266+ } else {
267+ dx = - dx ;
268+ sx = -1 ;
269+ }
270+
271+ mp_int_t dy = y2 - y1 ;
272+ mp_int_t sy ;
273+ if (dy > 0 ) {
274+ sy = 1 ;
275+ } else {
276+ dy = - dy ;
277+ sy = -1 ;
278+ }
279+
280+ bool steep ;
281+ if (dy > dx ) {
282+ mp_int_t temp ;
283+ temp = x1 ; x1 = y1 ; y1 = temp ;
284+ temp = dx ; dx = dy ; dy = temp ;
285+ temp = sx ; sx = sy ; sy = temp ;
286+ steep = true;
287+ } else {
288+ steep = false;
289+ }
290+
291+ mp_int_t e = 2 * dy - dx ;
292+ for (mp_int_t i = 0 ; i < dx ; ++ i ) {
293+ if (steep ) {
294+ setpixel (self , y1 , x1 , col );
295+ } else {
296+ setpixel (self , x1 , y1 , col );
297+ }
298+ while (e >= 0 ) {
299+ y1 += sy ;
300+ e -= 2 * dx ;
301+ }
302+ x1 += sx ;
303+ e += 2 * dy ;
304+ }
305+
306+ setpixel (self , x2 , y2 , col );
307+
308+ return mp_const_none ;
309+ }
310+ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (framebuf_line_obj , 6 , 6 , framebuf_line );
311+
199312STATIC mp_obj_t framebuf_blit (size_t n_args , const mp_obj_t * args ) {
200313 mp_obj_framebuf_t * self = MP_OBJ_TO_PTR (args [0 ]);
201314 mp_obj_framebuf_t * source = MP_OBJ_TO_PTR (args [1 ]);
@@ -314,6 +427,10 @@ STATIC const mp_rom_map_elem_t framebuf_locals_dict_table[] = {
314427 { MP_ROM_QSTR (MP_QSTR_fill ), MP_ROM_PTR (& framebuf_fill_obj ) },
315428 { MP_ROM_QSTR (MP_QSTR_fill_rect ), MP_ROM_PTR (& framebuf_fill_rect_obj ) },
316429 { MP_ROM_QSTR (MP_QSTR_pixel ), MP_ROM_PTR (& framebuf_pixel_obj ) },
430+ { MP_ROM_QSTR (MP_QSTR_hline ), MP_ROM_PTR (& framebuf_hline_obj ) },
431+ { MP_ROM_QSTR (MP_QSTR_vline ), MP_ROM_PTR (& framebuf_vline_obj ) },
432+ { MP_ROM_QSTR (MP_QSTR_rect ), MP_ROM_PTR (& framebuf_rect_obj ) },
433+ { MP_ROM_QSTR (MP_QSTR_line ), MP_ROM_PTR (& framebuf_line_obj ) },
317434 { MP_ROM_QSTR (MP_QSTR_blit ), MP_ROM_PTR (& framebuf_blit_obj ) },
318435 { MP_ROM_QSTR (MP_QSTR_scroll ), MP_ROM_PTR (& framebuf_scroll_obj ) },
319436 { MP_ROM_QSTR (MP_QSTR_text ), MP_ROM_PTR (& framebuf_text_obj ) },
0 commit comments