Skip to content

Commit 374ed31

Browse files
committed
extmod/modframebuf: Add hline, vline, rect and line methods.
These are basic drawing primitives. They work in a generic way on all framebuf formats by calling the underlying setpixel or fill_rect C-level primitives.
1 parent 0db3a41 commit 374ed31

1 file changed

Lines changed: 129 additions & 12 deletions

File tree

extmod/modframebuf.c

Lines changed: 129 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
116131
STATIC 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
}
197201
STATIC 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+
199312
STATIC 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

Comments
 (0)