@@ -868,7 +868,86 @@ STATIC mp_obj_t bitmaptools_dither(size_t n_args, const mp_obj_t *pos_args, mp_m
868868 return mp_const_none ;
869869}
870870MP_DEFINE_CONST_FUN_OBJ_KW (bitmaptools_dither_obj , 0 , bitmaptools_dither );
871+ // requires all 5 arguments
871872
873+ //| def draw_circle(
874+ //| dest_bitmap: displayio.Bitmap, x: int, y: int, radius: int, value: int
875+ //| ) -> None:
876+ //| """Draws a circle into a bitmap specified using a center (x0,y0) and radius r.
877+ //|
878+ //| :param bitmap dest_bitmap: Destination bitmap that will be written into
879+ //| :param int x: x-pixel position of the circle's center
880+ //| :param int y: y-pixel position of the circle's center
881+ //| :param int radius: circle's radius
882+ //| :param int value: Bitmap palette index that will be written into the
883+ //| circle in the destination bitmap
884+ //|
885+ //| .. code-block:: Python
886+ //|
887+ //| import board
888+ //| import displayio
889+ //| import bitmaptools
890+ //|
891+ //| display = board.DISPLAY
892+ //| main_group = displayio.Group()
893+ //| display.root_group = main_group
894+ //|
895+ //| palette = displayio.Palette(2)
896+ //| palette[0] = 0xffffff
897+ //| palette[1] = 0x440044
898+ //|
899+ //| bmp = displayio.Bitmap(128,128, 2)
900+ //| bmp.fill(0)
901+ //|
902+ //| bitmaptools.circle(64,64, 32, 1)
903+ //|
904+ //| tilegrid = displayio.TileGrid(bitmap=bmp, pixel_shader=palette)
905+ //| main_group.append(tilegrid)
906+ //|
907+ //| while True:
908+ //| pass
909+ //|
910+ //| """
911+ //|
912+ //| ...
913+ //|
914+ STATIC mp_obj_t bitmaptools_obj_draw_circle (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
915+ enum {ARG_dest_bitmap , ARG_x , ARG_y , ARG_radius , ARG_value };
916+
917+ static const mp_arg_t allowed_args [] = {
918+ {MP_QSTR_dest_bitmap , MP_ARG_REQUIRED | MP_ARG_OBJ },
919+ {MP_QSTR_x , MP_ARG_REQUIRED | MP_ARG_INT },
920+ {MP_QSTR_y , MP_ARG_REQUIRED | MP_ARG_INT },
921+ {MP_QSTR_radius , MP_ARG_REQUIRED | MP_ARG_INT },
922+ {MP_QSTR_value , MP_ARG_REQUIRED | MP_ARG_INT },
923+ };
924+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
925+ mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
926+
927+ displayio_bitmap_t * destination = MP_OBJ_TO_PTR (args [ARG_dest_bitmap ].u_obj ); // the destination bitmap
928+
929+ uint32_t value , color_depth ;
930+ value = args [ARG_value ].u_int ;
931+ color_depth = (1 << destination -> bits_per_value );
932+ if (color_depth <= value ) {
933+ mp_raise_ValueError (translate ("out of range of target" ));
934+ }
935+
936+
937+ int16_t x = args [ARG_x ].u_int ;
938+ int16_t y = args [ARG_y ].u_int ;
939+ int16_t radius = args [ARG_radius ].u_int ;
940+
941+ mp_arg_validate_int_range (x , 0 , destination -> width , MP_QSTR_x );
942+ mp_arg_validate_int_range (y , 0 , destination -> height , MP_QSTR_y );
943+ mp_arg_validate_int_min (radius , 0 , MP_QSTR_radius );
944+
945+ common_hal_bitmaptools_draw_circle (destination , x , y , radius , value );
946+
947+ return mp_const_none ;
948+ }
949+
950+ MP_DEFINE_CONST_FUN_OBJ_KW (bitmaptools_draw_circle_obj , 0 , bitmaptools_obj_draw_circle );
872951
873952STATIC const mp_rom_map_elem_t bitmaptools_module_globals_table [] = {
874953 { MP_ROM_QSTR (MP_QSTR___name__ ), MP_ROM_QSTR (MP_QSTR_bitmaptools ) },
@@ -880,6 +959,7 @@ STATIC const mp_rom_map_elem_t bitmaptools_module_globals_table[] = {
880959 { MP_ROM_QSTR (MP_QSTR_boundary_fill ), MP_ROM_PTR (& bitmaptools_boundary_fill_obj ) },
881960 { MP_ROM_QSTR (MP_QSTR_draw_line ), MP_ROM_PTR (& bitmaptools_draw_line_obj ) },
882961 { MP_ROM_QSTR (MP_QSTR_draw_polygon ), MP_ROM_PTR (& bitmaptools_draw_polygon_obj ) },
962+ { MP_ROM_QSTR (MP_QSTR_draw_circle ), MP_ROM_PTR (& bitmaptools_draw_circle_obj ) },
883963 { MP_ROM_QSTR (MP_QSTR_dither ), MP_ROM_PTR (& bitmaptools_dither_obj ) },
884964 { MP_ROM_QSTR (MP_QSTR_DitherAlgorithm ), MP_ROM_PTR (& bitmaptools_dither_algorithm_type ) },
885965};
0 commit comments