Skip to content

Commit 0b3099a

Browse files
committed
adding bitmaptools circle
1 parent 7541304 commit 0b3099a

File tree

3 files changed

+114
-1
lines changed

3 files changed

+114
-1
lines changed

shared-bindings/bitmaptools/__init__.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,55 @@ STATIC mp_obj_t bitmaptools_dither(size_t n_args, const mp_obj_t *pos_args, mp_m
868868
return mp_const_none;
869869
}
870870
MP_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, x0: int, y0: 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 x0: x-pixel position of the circle's center
880+
//| :param int y0: 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+
//|
886+
STATIC mp_obj_t bitmaptools_obj_draw_circle(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
887+
enum {ARG_dest_bitmap, ARG_x0, ARG_y0, ARG_radius, ARG_value};
888+
889+
static const mp_arg_t allowed_args[] = {
890+
{MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}},
891+
{MP_QSTR_x0, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}},
892+
{MP_QSTR_y0, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}},
893+
{MP_QSTR_radius, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}},
894+
{MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}},
895+
};
896+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
897+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
898+
899+
displayio_bitmap_t *destination = MP_OBJ_TO_PTR(args[ARG_dest_bitmap].u_obj); // the destination bitmap
900+
901+
uint32_t value, color_depth;
902+
value = args[ARG_value].u_int;
903+
color_depth = (1 << destination->bits_per_value);
904+
if (color_depth <= value) {
905+
mp_raise_ValueError(translate("out of range of target"));
906+
}
907+
908+
909+
int16_t x0 = args[ARG_x0].u_int;
910+
int16_t y0 = args[ARG_y0].u_int;
911+
int16_t radius = args[ARG_radius].u_int;
912+
913+
914+
common_hal_bitmaptools_draw_circle(destination, x0, y0, radius, value);
915+
916+
return mp_const_none;
917+
}
918+
919+
MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_circle_obj, 0, bitmaptools_obj_draw_circle);
872920

873921
STATIC const mp_rom_map_elem_t bitmaptools_module_globals_table[] = {
874922
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bitmaptools) },
@@ -880,6 +928,7 @@ STATIC const mp_rom_map_elem_t bitmaptools_module_globals_table[] = {
880928
{ MP_ROM_QSTR(MP_QSTR_boundary_fill), MP_ROM_PTR(&bitmaptools_boundary_fill_obj) },
881929
{ MP_ROM_QSTR(MP_QSTR_draw_line), MP_ROM_PTR(&bitmaptools_draw_line_obj) },
882930
{ MP_ROM_QSTR(MP_QSTR_draw_polygon), MP_ROM_PTR(&bitmaptools_draw_polygon_obj) },
931+
{ MP_ROM_QSTR(MP_QSTR_draw_circle), MP_ROM_PTR(&bitmaptools_draw_circle_obj) },
883932
{ MP_ROM_QSTR(MP_QSTR_dither), MP_ROM_PTR(&bitmaptools_dither_obj) },
884933
{ MP_ROM_QSTR(MP_QSTR_DitherAlgorithm), MP_ROM_PTR(&bitmaptools_dither_algorithm_type) },
885934
};

shared-bindings/bitmaptools/__init__.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ void common_hal_bitmaptools_draw_line(displayio_bitmap_t *destination,
6464
int16_t x1, int16_t y1,
6565
uint32_t value);
6666

67+
void common_hal_bitmaptools_draw_circle(displayio_bitmap_t *destination,
68+
int16_t x0, int16_t y0,
69+
int16_t radius,
70+
uint32_t value);
71+
6772
void common_hal_bitmaptools_draw_polygon(displayio_bitmap_t *destination, void *xs, void *ys, size_t points_len, int point_size, uint32_t value, bool close);
6873
void common_hal_bitmaptools_readinto(displayio_bitmap_t *self, mp_obj_t *file, int element_size, int bits_per_pixel, bool reverse_pixels_in_word, bool swap_bytes, bool reverse_rows);
6974
void common_hal_bitmaptools_arrayblit(displayio_bitmap_t *self, void *data, int element_size, int x1, int y1, int x2, int y2, bool skip_specified, uint32_t skip_index);

shared-module/bitmaptools/__init__.c

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2021 Kevin Matocha
6+
* Copyright (c) 2021 Kevin Matocha, Jose David Montoya
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal
@@ -40,6 +40,9 @@
4040
#include <stdio.h>
4141
#include <string.h>
4242

43+
#define BITMAP_DEBUG(...) (void)0
44+
// #define BITMAP_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__)
45+
4346
void common_hal_bitmaptools_rotozoom(displayio_bitmap_t *self, int16_t ox, int16_t oy,
4447
int16_t dest_clip0_x, int16_t dest_clip0_y,
4548
int16_t dest_clip1_x, int16_t dest_clip1_y,
@@ -918,3 +921,59 @@ void common_hal_bitmaptools_alphablend(displayio_bitmap_t *dest, displayio_bitma
918921
}
919922
}
920923
}
924+
925+
STATIC void draw_circle(displayio_bitmap_t *destination,
926+
int16_t x0, int16_t y0,
927+
int16_t radius, uint32_t value) {
928+
929+
int16_t d, y;
930+
931+
mp_arg_validate_int_range(x0, SHRT_MIN, SHRT_MAX, MP_QSTR_x0);
932+
mp_arg_validate_int_range(y0, SHRT_MIN, SHRT_MAX, MP_QSTR_y0);
933+
934+
BITMAP_DEBUG("x, y, radius (%4d, %4d, %4d)\n", x0, y0, radius);
935+
936+
y = radius;
937+
d = 3 - 2 * radius;
938+
939+
// Bresenham's circle algorithm
940+
for (int x = 0; x <= y; x++) {
941+
displayio_bitmap_write_pixel(destination, x + x0, y + y0, value);
942+
displayio_bitmap_write_pixel(destination, -x + x0, -y + y0, value);
943+
displayio_bitmap_write_pixel(destination, -x + x0, y + y0, value);
944+
displayio_bitmap_write_pixel(destination, x + x0, -y + y0, value);
945+
displayio_bitmap_write_pixel(destination, y + x0, x + y0, value);
946+
displayio_bitmap_write_pixel(destination, -y + x0, x + y0, value);
947+
displayio_bitmap_write_pixel(destination, -y + x0, -x + y0, value);
948+
displayio_bitmap_write_pixel(destination, y + x0, -x + y0, value);
949+
if (d <= 0) {
950+
d = d + (4 * x) + 6;
951+
} else {
952+
d = d + 4 * (x - y) + 10;
953+
y = y - 1;
954+
}
955+
}
956+
}
957+
958+
void common_hal_bitmaptools_draw_circle(displayio_bitmap_t *destination,
959+
int16_t x0, int16_t y0,
960+
int16_t radius,
961+
uint32_t value) {
962+
963+
964+
// update the dirty area
965+
int16_t xbb0, xbb1, ybb0, ybb1;
966+
967+
xbb0 = x0 - radius;
968+
xbb1 = x0 + radius;
969+
ybb0 = y0 - radius;
970+
ybb1 = y0 + radius;
971+
972+
displayio_area_t area = { xbb0, ybb0, xbb1, ybb1, NULL };
973+
displayio_area_t bitmap_area = { 0, 0, destination->width, destination->height, NULL };
974+
displayio_area_compute_overlap(&area, &bitmap_area, &area);
975+
976+
displayio_bitmap_set_dirty_area(destination, &area);
977+
978+
draw_circle(destination, x0, y0, radius, value);
979+
}

0 commit comments

Comments
 (0)