@@ -949,6 +949,132 @@ STATIC mp_obj_t bitmaptools_obj_draw_circle(size_t n_args, const mp_obj_t *pos_a
949
949
950
950
MP_DEFINE_CONST_FUN_OBJ_KW (bitmaptools_draw_circle_obj , 0 , bitmaptools_obj_draw_circle );
951
951
952
+ //| def blit(
953
+ //| dest_bitmap: displayio.Bitmap,
954
+ //| source_bitmap: displayio.Bitmap,
955
+ //| x: int,
956
+ //| y: int,
957
+ //| *,
958
+ //| x1: int,
959
+ //| y1: int,
960
+ //| x2: int,
961
+ //| y2: int,
962
+ //| skip_source_index: int,
963
+ //| skip_dest_index: int
964
+ //| ) -> None:
965
+ //| """Inserts the source_bitmap region defined by rectangular boundaries
966
+ //| (x1,y1) and (x2,y2) into the bitmap at the specified (x,y) location.
967
+ //|
968
+ //| :param bitmap dest_bitmap: Destination bitmap that the area will be copied into.
969
+ //| :param bitmap source_bitmap: Source bitmap that contains the graphical region to be copied
970
+ //| :param int x: Horizontal pixel location in bitmap where source_bitmap upper-left
971
+ //| corner will be placed
972
+ //| :param int y: Vertical pixel location in bitmap where source_bitmap upper-left
973
+ //| corner will be placed
974
+ //| :param int x1: Minimum x-value for rectangular bounding box to be copied from the source bitmap
975
+ //| :param int y1: Minimum y-value for rectangular bounding box to be copied from the source bitmap
976
+ //| :param int x2: Maximum x-value (exclusive) for rectangular bounding box to be copied from the source bitmap
977
+ //| :param int y2: Maximum y-value (exclusive) for rectangular bounding box to be copied from the source bitmap
978
+ //| :param int skip_source_index: bitmap palette index in the source that will not be copied,
979
+ //| set to None to copy all pixels
980
+ //| :param int skip_dest_index: bitmap palette index in the destination bitmap that will not get overwritten
981
+ //| by the pixels from the source"""
982
+ //| ...
983
+ //|
984
+ STATIC mp_obj_t bitmaptools_obj_blit (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
985
+ enum {ARG_destination , ARG_source , ARG_x , ARG_y , ARG_x1 , ARG_y1 , ARG_x2 , ARG_y2 , ARG_skip_source_index , ARG_skip_dest_index };
986
+ static const mp_arg_t allowed_args [] = {
987
+ {MP_QSTR_dest_bitmap , MP_ARG_REQUIRED | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
988
+ {MP_QSTR_source_bitmap , MP_ARG_REQUIRED | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
989
+ {MP_QSTR_x , MP_ARG_REQUIRED | MP_ARG_INT , {.u_obj = MP_OBJ_NULL } },
990
+ {MP_QSTR_y , MP_ARG_REQUIRED | MP_ARG_INT , {.u_obj = MP_OBJ_NULL } },
991
+ {MP_QSTR_x1 , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0 } },
992
+ {MP_QSTR_y1 , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0 } },
993
+ {MP_QSTR_x2 , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = mp_const_none } }, // None convert to source->width
994
+ {MP_QSTR_y2 , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = mp_const_none } }, // None convert to source->height
995
+ {MP_QSTR_skip_source_index , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = mp_const_none } },
996
+ {MP_QSTR_skip_dest_index , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = mp_const_none } },
997
+ };
998
+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
999
+ // mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
1000
+ mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
1001
+
1002
+ // displayio_bitmap_t *self = MP_OBJ_TO_PTR(pos_args[0]);
1003
+ displayio_bitmap_t * destination = mp_arg_validate_type (args [ARG_destination ].u_obj , & displayio_bitmap_type , MP_QSTR_dest_bitmap );
1004
+ // check_for_deinit(destination);
1005
+
1006
+ // Check x,y are within self (target) bitmap boundary
1007
+ int16_t x = mp_arg_validate_int_range (args [ARG_x ].u_int , 0 , MAX (0 , destination -> width - 1 ), MP_QSTR_x );
1008
+ int16_t y = mp_arg_validate_int_range (args [ARG_y ].u_int , 0 , MAX (0 , destination -> height - 1 ), MP_QSTR_y );
1009
+
1010
+
1011
+ displayio_bitmap_t * source = mp_arg_validate_type (args [ARG_source ].u_obj , & displayio_bitmap_type , MP_QSTR_source_bitmap );
1012
+
1013
+
1014
+ // ensure that the target bitmap (self) has at least as many `bits_per_value` as the source
1015
+ if (destination -> bits_per_value < source -> bits_per_value ) {
1016
+ mp_raise_ValueError (translate ("source palette too large" ));
1017
+ }
1018
+
1019
+ // Check x1,y1,x2,y2 are within source bitmap boundary
1020
+ int16_t x1 = mp_arg_validate_int_range (args [ARG_x1 ].u_int , 0 , MAX (0 , source -> width - 1 ), MP_QSTR_x1 );
1021
+ int16_t y1 = mp_arg_validate_int_range (args [ARG_y1 ].u_int , 0 , MAX (0 , source -> height - 1 ), MP_QSTR_y1 );
1022
+ int16_t x2 , y2 ;
1023
+ // if x2 or y2 is None, then set as the maximum size of the source bitmap
1024
+ if (args [ARG_x2 ].u_obj == mp_const_none ) {
1025
+ x2 = source -> width ;
1026
+ } else {
1027
+ x2 = mp_arg_validate_int_range (mp_obj_get_int (args [ARG_x2 ].u_obj ), 0 , source -> width , MP_QSTR_x2 );
1028
+ }
1029
+ // int16_t y2;
1030
+ if (args [ARG_y2 ].u_obj == mp_const_none ) {
1031
+ y2 = source -> height ;
1032
+ } else {
1033
+ y2 = mp_arg_validate_int_range (mp_obj_get_int (args [ARG_y2 ].u_obj ), 0 , source -> height , MP_QSTR_y2 );
1034
+ }
1035
+
1036
+ // Ensure x1 < x2 and y1 < y2
1037
+ if (x1 > x2 ) {
1038
+ int16_t temp = x2 ;
1039
+ x2 = x1 ;
1040
+ x1 = temp ;
1041
+ }
1042
+ if (y1 > y2 ) {
1043
+ int16_t temp = y2 ;
1044
+ y2 = y1 ;
1045
+ y1 = temp ;
1046
+ }
1047
+
1048
+ uint32_t skip_source_index ;
1049
+ bool skip_source_index_none ; // flag whether skip_value was None
1050
+
1051
+ if (args [ARG_skip_source_index ].u_obj == mp_const_none ) {
1052
+ skip_source_index = 0 ;
1053
+ skip_source_index_none = true;
1054
+ } else {
1055
+ skip_source_index = mp_obj_get_int (args [ARG_skip_source_index ].u_obj );
1056
+ skip_source_index_none = false;
1057
+ }
1058
+
1059
+ uint32_t skip_dest_index ;
1060
+ bool skip_dest_index_none ; // flag whether skip_self_value was None
1061
+
1062
+ if (args [ARG_skip_dest_index ].u_obj == mp_const_none ) {
1063
+ skip_dest_index = 0 ;
1064
+ skip_dest_index_none = true;
1065
+ } else {
1066
+ skip_dest_index = mp_obj_get_int (args [ARG_skip_dest_index ].u_obj );
1067
+ skip_dest_index_none = false;
1068
+ }
1069
+
1070
+ common_hal_bitmaptools_blit (destination , source , x , y , x1 , y1 , x2 , y2 , skip_source_index , skip_source_index_none , skip_dest_index ,
1071
+ skip_dest_index_none );
1072
+
1073
+ return mp_const_none ;
1074
+ }
1075
+ MP_DEFINE_CONST_FUN_OBJ_KW (bitmaptools_blit_obj , 1 , bitmaptools_obj_blit );
1076
+
1077
+
952
1078
STATIC const mp_rom_map_elem_t bitmaptools_module_globals_table [] = {
953
1079
{ MP_ROM_QSTR (MP_QSTR___name__ ), MP_ROM_QSTR (MP_QSTR_bitmaptools ) },
954
1080
{ MP_ROM_QSTR (MP_QSTR_readinto ), MP_ROM_PTR (& bitmaptools_readinto_obj ) },
@@ -960,6 +1086,7 @@ STATIC const mp_rom_map_elem_t bitmaptools_module_globals_table[] = {
960
1086
{ MP_ROM_QSTR (MP_QSTR_draw_line ), MP_ROM_PTR (& bitmaptools_draw_line_obj ) },
961
1087
{ MP_ROM_QSTR (MP_QSTR_draw_polygon ), MP_ROM_PTR (& bitmaptools_draw_polygon_obj ) },
962
1088
{ MP_ROM_QSTR (MP_QSTR_draw_circle ), MP_ROM_PTR (& bitmaptools_draw_circle_obj ) },
1089
+ { MP_ROM_QSTR (MP_QSTR_blit ), MP_ROM_PTR (& bitmaptools_blit_obj ) },
963
1090
{ MP_ROM_QSTR (MP_QSTR_dither ), MP_ROM_PTR (& bitmaptools_dither_obj ) },
964
1091
{ MP_ROM_QSTR (MP_QSTR_DitherAlgorithm ), MP_ROM_PTR (& bitmaptools_dither_algorithm_type ) },
965
1092
};
0 commit comments