diff --git a/micropython/modules/picographics/picographics.c b/micropython/modules/picographics/picographics.c index 523ac5e7..c8e00cc2 100644 --- a/micropython/modules/picographics/picographics.c +++ b/micropython/modules/picographics/picographics.c @@ -3,6 +3,7 @@ // Module functions STATIC MP_DEFINE_CONST_FUN_OBJ_3(ModPicoGraphics_module_RGB332_obj, ModPicoGraphics_module_RGB332); STATIC MP_DEFINE_CONST_FUN_OBJ_3(ModPicoGraphics_module_RGB565_obj, ModPicoGraphics_module_RGB565); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(ModPicoGraphics_get_required_buffer_size_obj, ModPicoGraphics_get_required_buffer_size); // Class Methods MP_DEFINE_CONST_FUN_OBJ_1(ModPicoGraphics_update_obj, ModPicoGraphics_update); @@ -80,6 +81,7 @@ const mp_obj_type_t ModPicoGraphics_type = { STATIC const mp_map_elem_t picographics_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_picographics) }, { MP_ROM_QSTR(MP_QSTR_PicoGraphics), (mp_obj_t)&ModPicoGraphics_type }, + { MP_ROM_QSTR(MP_QSTR_get_buffer_size), MP_ROM_PTR(&ModPicoGraphics_get_required_buffer_size_obj) }, { MP_ROM_QSTR(MP_QSTR_RGB332), MP_ROM_PTR(&ModPicoGraphics_module_RGB332_obj) }, { MP_ROM_QSTR(MP_QSTR_RGB565), MP_ROM_PTR(&ModPicoGraphics_module_RGB565_obj) }, diff --git a/micropython/modules/picographics/picographics.cpp b/micropython/modules/picographics/picographics.cpp index 46c7eef3..4d79c1e9 100644 --- a/micropython/modules/picographics/picographics.cpp +++ b/micropython/modules/picographics/picographics.cpp @@ -27,6 +27,52 @@ typedef struct _ModPicoGraphics_obj_t { void *buffer; } ModPicoGraphics_obj_t; +bool get_display_resolution(PicoGraphicsDisplay display, int &width, int &height) { + switch(display) { + case DISPLAY_PICO_DISPLAY: + width = 240; + height = 135; + break; + case DISPLAY_PICO_DISPLAY_2: + case DISPLAY_TUFTY_2040: + width = 320; + height = 240; + break; + case DISPLAY_PICO_EXPLORER: + case DISPLAY_LCD_240X240: + case DISPLAY_ENVIRO_PLUS: + width = 240; + height = 240; + break; + case DISPLAY_ROUND_LCD_240X240: + width = 240; + height = 240; + break; + case DISPLAY_LCD_160X80: + width = 160; + height = 80; + break; + default: + return false; + } + return true; +} + +size_t get_required_buffer_size(PicoGraphicsPenType pen_type, uint width, uint height) { + switch(pen_type) { + case PEN_P4: + return PicoGraphics_PenP4::buffer_size(width, height); + case PEN_P8: + return PicoGraphics_PenP8::buffer_size(width, height); + case PEN_RGB332: + return PicoGraphics_PenRGB332::buffer_size(width, height); + case PEN_RGB565: + return PicoGraphics_PenRGB565::buffer_size(width, height); + default: + return 0; + } +} + mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { ModPicoGraphics_obj_t *self = nullptr; @@ -47,42 +93,14 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size self->base.type = &ModPicoGraphics_type; Rotation rotate = (Rotation)args[ARG_rotate].u_int; - bool round = false; - int width = 0; - int height = 0; PicoGraphicsPenType pen_type = (PicoGraphicsPenType)args[ARG_pen_type].u_int; PicoGraphicsDisplay display = (PicoGraphicsDisplay)args[ARG_display].u_int; - switch(display) { - case DISPLAY_PICO_DISPLAY: - width = 240; - height = 135; - break; - case DISPLAY_PICO_DISPLAY_2: - case DISPLAY_TUFTY_2040: - width = 320; - height = 240; - break; - case DISPLAY_PICO_EXPLORER: - case DISPLAY_LCD_240X240: - case DISPLAY_ENVIRO_PLUS: - width = 240; - height = 240; - break; - case DISPLAY_ROUND_LCD_240X240: - width = 240; - height = 240; - round = true; - break; - case DISPLAY_LCD_160X80: - width = 160; - height = 80; - break; - default: - mp_raise_ValueError("Unsupported display!"); - break; // unreachable - } + bool round = display == DISPLAY_ROUND_LCD_240X240; + int width = 0; + int height = 0; + if(!get_display_resolution(display, width, height)) mp_raise_ValueError("Unsupported display!"); // Try to create an appropriate display driver if (display == DISPLAY_TUFTY_2040) { @@ -115,24 +133,8 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size } // Create or fetch buffer - size_t required_size = 0; - switch(pen_type) { - case PEN_P4: - required_size = PicoGraphics_PenP4::buffer_size(width, height); - break; - case PEN_P8: - required_size = PicoGraphics_PenP8::buffer_size(width, height); - break; - case PEN_RGB332: - required_size = PicoGraphics_PenRGB332::buffer_size(width, height); - break; - case PEN_RGB565: - required_size = PicoGraphics_PenRGB565::buffer_size(width, height); - break; - default: - mp_raise_ValueError("Unsupported display!"); - break; // unreachable - } + size_t required_size = get_required_buffer_size(pen_type, width, height); + if(required_size == 0) mp_raise_ValueError("Unsupported pen type!"); if (args[ARG_buffer].u_obj != mp_const_none) { mp_buffer_info_t bufinfo; @@ -203,6 +205,18 @@ mp_obj_t ModPicoGraphics_set_framebuffer(mp_obj_t self_in, mp_obj_t framebuffer) return mp_const_none; } +mp_obj_t ModPicoGraphics_get_required_buffer_size(mp_obj_t display_in, mp_obj_t pen_type_in) { + PicoGraphicsPenType pen_type = (PicoGraphicsPenType)mp_obj_get_int(pen_type_in); + PicoGraphicsDisplay display = (PicoGraphicsDisplay)mp_obj_get_int(display_in); + int width = 0; + int height = 0; + if(!get_display_resolution(display, width, height)) mp_raise_ValueError("Unsupported display!"); + size_t required_size = get_required_buffer_size(pen_type, width, height); + if(required_size == 0) mp_raise_ValueError("Unsupported pen type!"); + + return mp_obj_new_int(required_size); +} + mp_obj_t ModPicoGraphics_get_bounds(mp_obj_t self_in) { ModPicoGraphics_obj_t *self = MP_OBJ_TO_PTR2(self_in, ModPicoGraphics_obj_t); mp_obj_t tuple[2] = { diff --git a/micropython/modules/picographics/picographics.h b/micropython/modules/picographics/picographics.h index 066e5126..ded38c35 100644 --- a/micropython/modules/picographics/picographics.h +++ b/micropython/modules/picographics/picographics.h @@ -26,6 +26,7 @@ extern const mp_obj_type_t ModPicoGraphics_type; // Module functions extern mp_obj_t ModPicoGraphics_module_RGB332(mp_obj_t r, mp_obj_t g, mp_obj_t b); extern mp_obj_t ModPicoGraphics_module_RGB565(mp_obj_t r, mp_obj_t g, mp_obj_t b); +extern mp_obj_t ModPicoGraphics_get_required_buffer_size(mp_obj_t display_in, mp_obj_t pen_type_in); // Class methods extern mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);