Skip to content

Commit b6178c9

Browse files
committed
WIP on exposing fill_area
1 parent 7fd1a6c commit b6178c9

1 file changed

Lines changed: 116 additions & 0 deletions

File tree

shared-bindings/displayio/Display.c

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,17 +348,133 @@ const mp_obj_property_t displayio_display_bus_obj = {
348348
};
349349

350350

351+
//| .. attribute:: screenshot
352+
//|
353+
//| Take a screenshot.
354+
//|
355+
//|
356+
/* STATIC mp_obj_t displayio_display_obj_get_screenshot(mp_obj_t self_in) { */
357+
/* displayio_display_obj_t *self = native_display(self_in); */
358+
/* return mp_const_none; */
359+
/* } */
360+
/* MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_screenshot_obj, displayio_display_obj_get_screenshot); */
361+
362+
/* const mp_obj_property_t displayio_display_screenshot_obj = { */
363+
/* .base.type = &mp_type_property, */
364+
/* .proxy = {(mp_obj_t)&displayio_display_get_screenshot_obj, */
365+
/* (mp_obj_t)&mp_const_none_obj, */
366+
/* (mp_obj_t)&mp_const_none_obj}, */
367+
/* }; */
368+
369+
370+
#include "py/objarray.h"
371+
mp_obj_array_t *array_new(char typecode, size_t n);
372+
mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value);
373+
374+
//| .. method:: fill_area(x, y, w, h)
375+
//|
376+
//| Switches to displaying the given group of layers. When group is None, the default
377+
//| CircuitPython terminal will be shown.
378+
//|
379+
//| :param int x: The left edge of the area
380+
//| :param int y: The top edge of the area
381+
//| :param int w: The width of the area
382+
//| :param int h: The height of the area
383+
STATIC mp_obj_t displayio_display_obj_fill_area(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
384+
enum { ARG_x, ARG_y, ARG_width, ARG_height };
385+
static const mp_arg_t allowed_args[] = {
386+
{ MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} },
387+
{ MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} },
388+
{ MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} },
389+
{ MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} },
390+
};
391+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
392+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
393+
394+
displayio_display_obj_t *self = native_display(pos_args[0]);
395+
mp_int_t x = args[ARG_x].u_int;
396+
mp_int_t y = args[ARG_y].u_int;
397+
mp_int_t w = args[ARG_width].u_int;
398+
mp_int_t h = args[ARG_height].u_int;
399+
400+
uint16_t buffer_size = 128; // In uint32_ts
401+
displayio_area_t area = {
402+
.x1 = x,
403+
.y1 = y,
404+
.x2 = x + w,
405+
.y2 = y + h
406+
};
407+
displayio_area_t clipped;
408+
// Clip the area to the display by overlapping the areas. If there is no overlap then we're done.
409+
if (!displayio_display_clip_area(self, &area, &clipped)) {
410+
return mp_const_none;
411+
}
412+
uint16_t subrectangles = 1;
413+
uint16_t rows_per_buffer = displayio_area_height(&clipped);
414+
uint8_t pixels_per_word = (sizeof(uint32_t) * 8) / self->colorspace.depth;
415+
uint16_t pixels_per_buffer = displayio_area_size(&clipped);
416+
if (displayio_area_size(&clipped) > buffer_size * pixels_per_word) {
417+
rows_per_buffer = buffer_size * pixels_per_word / displayio_area_width(&clipped);
418+
if (rows_per_buffer == 0) {
419+
rows_per_buffer = 1;
420+
}
421+
// If pixels are packed by column then ensure rows_per_buffer is on a byte boundary.
422+
if (self->colorspace.depth < 8 && !self->colorspace.pixels_in_byte_share_row) {
423+
uint8_t pixels_per_byte = 8 / self->colorspace.depth;
424+
if (rows_per_buffer % pixels_per_byte != 0) {
425+
rows_per_buffer -= rows_per_buffer % pixels_per_byte;
426+
}
427+
}
428+
subrectangles = displayio_area_height(&clipped) / rows_per_buffer;
429+
if (displayio_area_height(&clipped) % rows_per_buffer != 0) {
430+
subrectangles++;
431+
}
432+
pixels_per_buffer = rows_per_buffer * displayio_area_width(&clipped);
433+
buffer_size = pixels_per_buffer / pixels_per_word;
434+
if (pixels_per_buffer % pixels_per_word) {
435+
buffer_size += 1;
436+
}
437+
}
438+
439+
// Allocated and shared as a uint32_t array so the compiler knows the
440+
// alignment everywhere.
441+
uint32_t buffer[buffer_size];
442+
volatile uint32_t mask_length = (pixels_per_buffer / 32) + 1;
443+
uint32_t mask[mask_length];
444+
445+
for (uint16_t k = 0; k < mask_length; k++) {
446+
mask[k] = 0x00000000;
447+
}
448+
for (uint16_t k = 0; k < buffer_size; k++) {
449+
buffer[k] = 0x00000000;
450+
}
451+
452+
displayio_display_fill_area(self, &area, mask, buffer);
453+
454+
mp_obj_array_t *result = array_new(BYTEARRAY_TYPECODE, buffer_size);
455+
for (int offset = 0; offset < buffer_size; offset++) {
456+
array_subscr(result, MP_OBJ_NEW_SMALL_INT(offset), MP_OBJ_NEW_SMALL_INT(buffer[offset]));
457+
}
458+
return result;
459+
}
460+
MP_DEFINE_CONST_FUN_OBJ_KW(displayio_display_fill_area_obj, 1, displayio_display_obj_fill_area);
461+
462+
463+
464+
351465
STATIC const mp_rom_map_elem_t displayio_display_locals_dict_table[] = {
352466
{ MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_display_show_obj) },
353467
{ MP_ROM_QSTR(MP_QSTR_refresh_soon), MP_ROM_PTR(&displayio_display_refresh_soon_obj) },
354468
{ MP_ROM_QSTR(MP_QSTR_wait_for_frame), MP_ROM_PTR(&displayio_display_wait_for_frame_obj) },
469+
{ MP_ROM_QSTR(MP_QSTR_fill_area), MP_ROM_PTR(&displayio_display_fill_area_obj) },
355470

356471
{ MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&displayio_display_brightness_obj) },
357472
{ MP_ROM_QSTR(MP_QSTR_auto_brightness), MP_ROM_PTR(&displayio_display_auto_brightness_obj) },
358473

359474
{ MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_display_width_obj) },
360475
{ MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_display_height_obj) },
361476
{ MP_ROM_QSTR(MP_QSTR_bus), MP_ROM_PTR(&displayio_display_bus_obj) },
477+
// { MP_ROM_QSTR(MP_QSTR_screenshot), MP_ROM_PTR(&displayio_display_screenshot_obj) },
362478
};
363479
STATIC MP_DEFINE_CONST_DICT(displayio_display_locals_dict, displayio_display_locals_dict_table);
364480

0 commit comments

Comments
 (0)