Add support for scaling to _stage
On high-resolution displays we can use 2x2 or even 3x3 pixels.
This commit is contained in:
parent
95d2694bc3
commit
c1e5247d51
|
@ -50,7 +50,7 @@
|
||||||
//| Layer
|
//| Layer
|
||||||
//| Text
|
//| Text
|
||||||
//|
|
//|
|
||||||
//| .. function:: render(x0, y0, x1, y1, layers, buffer, display)
|
//| .. function:: render(x0, y0, x1, y1, layers, buffer, display[, scale])
|
||||||
//|
|
//|
|
||||||
//| Render and send to the display a fragment of the screen.
|
//| Render and send to the display a fragment of the screen.
|
||||||
//|
|
//|
|
||||||
|
@ -61,6 +61,7 @@
|
||||||
//| :param list layers: A list of the :py:class:`~_stage.Layer` objects.
|
//| :param list layers: A list of the :py:class:`~_stage.Layer` objects.
|
||||||
//| :param bytearray buffer: A buffer to use for rendering.
|
//| :param bytearray buffer: A buffer to use for rendering.
|
||||||
//| :param ~displayio.Display display: The display to use.
|
//| :param ~displayio.Display display: The display to use.
|
||||||
|
//| :param int scale: How many times should the image be scaled up.
|
||||||
//|
|
//|
|
||||||
//| There are also no sanity checks, outside of the basic overflow
|
//| There are also no sanity checks, outside of the basic overflow
|
||||||
//| checking. The caller is responsible for making the passed parameters
|
//| checking. The caller is responsible for making the passed parameters
|
||||||
|
@ -89,6 +90,10 @@ STATIC mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) {
|
||||||
mp_raise_TypeError(translate("argument num/types mismatch"));
|
mp_raise_TypeError(translate("argument num/types mismatch"));
|
||||||
}
|
}
|
||||||
displayio_display_obj_t *display = MP_OBJ_TO_PTR(native_display);
|
displayio_display_obj_t *display = MP_OBJ_TO_PTR(native_display);
|
||||||
|
uint8_t scale = 1;
|
||||||
|
if (n_args >= 8) {
|
||||||
|
scale = mp_obj_get_int(args[7]);
|
||||||
|
}
|
||||||
|
|
||||||
while (!displayio_display_begin_transaction(display)) {
|
while (!displayio_display_begin_transaction(display)) {
|
||||||
#ifdef MICROPY_VM_HOOK_LOOP
|
#ifdef MICROPY_VM_HOOK_LOOP
|
||||||
|
@ -103,12 +108,13 @@ STATIC mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) {
|
||||||
displayio_display_set_region_to_update(display, &area);
|
displayio_display_set_region_to_update(display, &area);
|
||||||
|
|
||||||
display->send(display->bus, true, &display->write_ram_command, 1);
|
display->send(display->bus, true, &display->write_ram_command, 1);
|
||||||
render_stage(x0, y0, x1, y1, layers, layers_size, buffer, buffer_size, display);
|
render_stage(x0, y0, x1, y1, layers, layers_size, buffer, buffer_size,
|
||||||
|
display, scale);
|
||||||
displayio_display_end_transaction(display);
|
displayio_display_end_transaction(display);
|
||||||
|
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stage_render_obj, 7, 7, stage_render);
|
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stage_render_obj, 7, 8, stage_render);
|
||||||
|
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t stage_module_globals_table[] = {
|
STATIC const mp_rom_map_elem_t stage_module_globals_table[] = {
|
||||||
|
|
|
@ -34,30 +34,35 @@
|
||||||
void render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
|
void render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
|
||||||
mp_obj_t *layers, size_t layers_size,
|
mp_obj_t *layers, size_t layers_size,
|
||||||
uint16_t *buffer, size_t buffer_size,
|
uint16_t *buffer, size_t buffer_size,
|
||||||
displayio_display_obj_t *display) {
|
displayio_display_obj_t *display, uint8_t scale) {
|
||||||
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
for (uint16_t y = y0; y < y1; ++y) {
|
for (uint16_t y = y0; y < y1; ++y) {
|
||||||
for (uint16_t x = x0; x < x1; ++x) {
|
for (uint8_t yscale = 0; yscale < scale; ++yscale) {
|
||||||
for (size_t layer = 0; layer < layers_size; ++layer) {
|
for (uint16_t x = x0; x < x1; ++x) {
|
||||||
uint16_t c = TRANSPARENT;
|
uint16_t c = TRANSPARENT;
|
||||||
layer_obj_t *obj = MP_OBJ_TO_PTR(layers[layer]);
|
for (size_t layer = 0; layer < layers_size; ++layer) {
|
||||||
if (obj->base.type == &mp_type_layer) {
|
layer_obj_t *obj = MP_OBJ_TO_PTR(layers[layer]);
|
||||||
c = get_layer_pixel(obj, x, y);
|
if (obj->base.type == &mp_type_layer) {
|
||||||
} else if (obj->base.type == &mp_type_text) {
|
c = get_layer_pixel(obj, x, y);
|
||||||
c = get_text_pixel((text_obj_t *)obj, x, y);
|
} else if (obj->base.type == &mp_type_text) {
|
||||||
|
c = get_text_pixel((text_obj_t *)obj, x, y);
|
||||||
|
}
|
||||||
|
if (c != TRANSPARENT) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (c != TRANSPARENT) {
|
for (uint8_t xscale = 0; xscale < scale; ++xscale) {
|
||||||
buffer[index] = c;
|
buffer[index] = c;
|
||||||
break;
|
index += 1;
|
||||||
|
// The buffer is full, send it.
|
||||||
|
if (index >= buffer_size) {
|
||||||
|
display->send(display->bus, false, ((uint8_t*)buffer),
|
||||||
|
buffer_size * 2);
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
index += 1;
|
|
||||||
// The buffer is full, send it.
|
|
||||||
if (index >= buffer_size) {
|
|
||||||
display->send(display->bus, false, ((uint8_t*)buffer), buffer_size * 2);
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Send the remaining data.
|
// Send the remaining data.
|
||||||
|
|
|
@ -37,6 +37,6 @@
|
||||||
void render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
|
void render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
|
||||||
mp_obj_t *layers, size_t layers_size,
|
mp_obj_t *layers, size_t layers_size,
|
||||||
uint16_t *buffer, size_t buffer_size,
|
uint16_t *buffer, size_t buffer_size,
|
||||||
displayio_display_obj_t *display);
|
displayio_display_obj_t *display, uint8_t scale);
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_SHARED_MODULE__STAGE
|
#endif // MICROPY_INCLUDED_SHARED_MODULE__STAGE
|
||||||
|
|
Loading…
Reference in New Issue