@@ -419,7 +419,7 @@ static mp_obj_t bitmaptools_alphablend(size_t n_args, const mp_obj_t *pos_args,
419419MP_DEFINE_CONST_FUN_OBJ_KW (bitmaptools_alphablend_obj , 0 , bitmaptools_alphablend );
420420
421421//| def replace_color(
422- //| dest_bitmap : displayio.Bitmap, old_color: int, new_color: int
422+ //| bitmap : displayio.Bitmap, old_color: int, new_color: int
423423//| ) -> None:
424424//| """Replace any pixels of ``old_color`` with ``new_color`` in the ``bitmap``
425425//|
@@ -458,6 +458,55 @@ static mp_obj_t bitmaptools_obj_replace_color(size_t n_args, const mp_obj_t *pos
458458
459459MP_DEFINE_CONST_FUN_OBJ_KW (bitmaptools_replace_color_obj , 0 , bitmaptools_obj_replace_color );
460460
461+ //| def outline(
462+ //| dest_bitmap: displayio.Bitmap, stamp_bitmap: display.Bitmap, target_color: int,
463+ //| ) -> None:
464+ //| """Add an outline around any pixels of ``target_color`` in ``dest_bitmap`` by
465+ //| bliting ``stamp_bitmap`` over every instance of ``target_color`` pixel.
466+ //| use a 3x3 bitmap to get a 1 pixel outline.
467+ //|
468+ //| :param displayio.Bitmap dest_bitmap: Bitmap that will be changed
469+ //| :param displayio.Bitmap stamp_bitmap: Bitmap that will blitted on
470+ //| each of ``target_color`` pixels.
471+ //| :param int target_color: Pixels of this Bitmap palette index
472+ // will have the outline drawn around them."""
473+ //| ...
474+ //|
475+ //|
476+ static mp_obj_t bitmaptools_obj_outline (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
477+ enum {ARG_dest_bitmap , ARG_stamp_bitmap , ARG_target_color };
478+
479+ static const mp_arg_t allowed_args [] = {
480+ {MP_QSTR_dest_bitmap , MP_ARG_REQUIRED | MP_ARG_OBJ },
481+ {MP_QSTR_stamp_bitmap , MP_ARG_REQUIRED | MP_ARG_OBJ },
482+ {MP_QSTR_target_color , MP_ARG_REQUIRED | MP_ARG_INT },
483+
484+ };
485+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
486+ mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
487+
488+
489+ displayio_bitmap_t * destination = MP_OBJ_TO_PTR (mp_arg_validate_type (args [ARG_dest_bitmap ].u_obj , & displayio_bitmap_type , MP_QSTR_bitmap ));
490+ displayio_bitmap_t * stamp = MP_OBJ_TO_PTR (mp_arg_validate_type (args [ARG_stamp_bitmap ].u_obj , & displayio_bitmap_type , MP_QSTR_bitmap ));
491+
492+
493+ uint32_t target_color ;
494+ target_color = args [ARG_target_color ].u_int ;
495+
496+ uint32_t dest_color_depth , stamp_color_depth ;
497+ dest_color_depth = (1 << destination -> bits_per_value );
498+ stamp_color_depth = (1 << stamp -> bits_per_value );
499+ if (stamp_color_depth > dest_color_depth ) {
500+ mp_raise_ValueError_varg (MP_ERROR_TEXT ("%q destination must have at least as many colors as stamp" ), MP_QSTR_color );
501+ }
502+
503+ common_hal_bitmaptools_outline (destination , stamp , target_color );
504+
505+ return mp_const_none ;
506+ }
507+
508+ MP_DEFINE_CONST_FUN_OBJ_KW (bitmaptools_outline_obj , 0 , bitmaptools_obj_outline );
509+
461510//| def fill_region(
462511//| dest_bitmap: displayio.Bitmap, x1: int, y1: int, x2: int, y2: int, value: int
463512//| ) -> None:
@@ -1144,6 +1193,7 @@ static const mp_rom_map_elem_t bitmaptools_module_globals_table[] = {
11441193 { MP_ROM_QSTR (MP_QSTR_arrayblit ), MP_ROM_PTR (& bitmaptools_arrayblit_obj ) },
11451194 { MP_ROM_QSTR (MP_QSTR_alphablend ), MP_ROM_PTR (& bitmaptools_alphablend_obj ) },
11461195 { MP_ROM_QSTR (MP_QSTR_replace_color ), MP_ROM_PTR (& bitmaptools_replace_color_obj ) },
1196+ { MP_ROM_QSTR (MP_QSTR_outline ), MP_ROM_PTR (& bitmaptools_outline_obj ) },
11471197 { MP_ROM_QSTR (MP_QSTR_fill_region ), MP_ROM_PTR (& bitmaptools_fill_region_obj ) },
11481198 { MP_ROM_QSTR (MP_QSTR_boundary_fill ), MP_ROM_PTR (& bitmaptools_boundary_fill_obj ) },
11491199 { MP_ROM_QSTR (MP_QSTR_draw_line ), MP_ROM_PTR (& bitmaptools_draw_line_obj ) },
0 commit comments