adding bitmaptools circle

This commit is contained in:
jposada202020 2023-03-22 18:44:45 -04:00
parent 75413040b6
commit 0b3099a9ff
3 changed files with 114 additions and 1 deletions

View File

@ -868,7 +868,55 @@ STATIC mp_obj_t bitmaptools_dither(size_t n_args, const mp_obj_t *pos_args, mp_m
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_dither_obj, 0, bitmaptools_dither);
// requires all 5 arguments
//| def draw_circle(
//| dest_bitmap: displayio.Bitmap, x0: int, y0: int, radius: int, value: int
//| ) -> None:
//| """Draws a circle into a bitmap specified using a center (x0,y0) and radius r.
//|
//| :param bitmap dest_bitmap: Destination bitmap that will be written into
//| :param int x0: x-pixel position of the circle's center
//| :param int y0: y-pixel position of the circle's center
//| :param int radius: circle's radius
//| :param int value: Bitmap palette index that will be written into the
//| circle in the destination bitmap"""
//| ...
//|
STATIC mp_obj_t bitmaptools_obj_draw_circle(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum {ARG_dest_bitmap, ARG_x0, ARG_y0, ARG_radius, ARG_value};
static const mp_arg_t allowed_args[] = {
{MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}},
{MP_QSTR_x0, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}},
{MP_QSTR_y0, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}},
{MP_QSTR_radius, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}},
{MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}},
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
displayio_bitmap_t *destination = MP_OBJ_TO_PTR(args[ARG_dest_bitmap].u_obj); // the destination bitmap
uint32_t value, color_depth;
value = args[ARG_value].u_int;
color_depth = (1 << destination->bits_per_value);
if (color_depth <= value) {
mp_raise_ValueError(translate("out of range of target"));
}
int16_t x0 = args[ARG_x0].u_int;
int16_t y0 = args[ARG_y0].u_int;
int16_t radius = args[ARG_radius].u_int;
common_hal_bitmaptools_draw_circle(destination, x0, y0, radius, value);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_circle_obj, 0, bitmaptools_obj_draw_circle);
STATIC const mp_rom_map_elem_t bitmaptools_module_globals_table[] = {
{ 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[] = {
{ MP_ROM_QSTR(MP_QSTR_boundary_fill), MP_ROM_PTR(&bitmaptools_boundary_fill_obj) },
{ MP_ROM_QSTR(MP_QSTR_draw_line), MP_ROM_PTR(&bitmaptools_draw_line_obj) },
{ MP_ROM_QSTR(MP_QSTR_draw_polygon), MP_ROM_PTR(&bitmaptools_draw_polygon_obj) },
{ MP_ROM_QSTR(MP_QSTR_draw_circle), MP_ROM_PTR(&bitmaptools_draw_circle_obj) },
{ MP_ROM_QSTR(MP_QSTR_dither), MP_ROM_PTR(&bitmaptools_dither_obj) },
{ MP_ROM_QSTR(MP_QSTR_DitherAlgorithm), MP_ROM_PTR(&bitmaptools_dither_algorithm_type) },
};

View File

@ -64,6 +64,11 @@ void common_hal_bitmaptools_draw_line(displayio_bitmap_t *destination,
int16_t x1, int16_t y1,
uint32_t value);
void common_hal_bitmaptools_draw_circle(displayio_bitmap_t *destination,
int16_t x0, int16_t y0,
int16_t radius,
uint32_t value);
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);
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);
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);

View File

@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2021 Kevin Matocha
* Copyright (c) 2021 Kevin Matocha, Jose David Montoya
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -40,6 +40,9 @@
#include <stdio.h>
#include <string.h>
#define BITMAP_DEBUG(...) (void)0
// #define BITMAP_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__)
void common_hal_bitmaptools_rotozoom(displayio_bitmap_t *self, int16_t ox, int16_t oy,
int16_t dest_clip0_x, int16_t dest_clip0_y,
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
}
}
}
STATIC void draw_circle(displayio_bitmap_t *destination,
int16_t x0, int16_t y0,
int16_t radius, uint32_t value) {
int16_t d, y;
mp_arg_validate_int_range(x0, SHRT_MIN, SHRT_MAX, MP_QSTR_x0);
mp_arg_validate_int_range(y0, SHRT_MIN, SHRT_MAX, MP_QSTR_y0);
BITMAP_DEBUG("x, y, radius (%4d, %4d, %4d)\n", x0, y0, radius);
y = radius;
d = 3 - 2 * radius;
// Bresenham's circle algorithm
for (int x = 0; x <= y; x++) {
displayio_bitmap_write_pixel(destination, x + x0, y + y0, value);
displayio_bitmap_write_pixel(destination, -x + x0, -y + y0, value);
displayio_bitmap_write_pixel(destination, -x + x0, y + y0, value);
displayio_bitmap_write_pixel(destination, x + x0, -y + y0, value);
displayio_bitmap_write_pixel(destination, y + x0, x + y0, value);
displayio_bitmap_write_pixel(destination, -y + x0, x + y0, value);
displayio_bitmap_write_pixel(destination, -y + x0, -x + y0, value);
displayio_bitmap_write_pixel(destination, y + x0, -x + y0, value);
if (d <= 0) {
d = d + (4 * x) + 6;
} else {
d = d + 4 * (x - y) + 10;
y = y - 1;
}
}
}
void common_hal_bitmaptools_draw_circle(displayio_bitmap_t *destination,
int16_t x0, int16_t y0,
int16_t radius,
uint32_t value) {
// update the dirty area
int16_t xbb0, xbb1, ybb0, ybb1;
xbb0 = x0 - radius;
xbb1 = x0 + radius;
ybb0 = y0 - radius;
ybb1 = y0 + radius;
displayio_area_t area = { xbb0, ybb0, xbb1, ybb1, NULL };
displayio_area_t bitmap_area = { 0, 0, destination->width, destination->height, NULL };
displayio_area_compute_overlap(&area, &bitmap_area, &area);
displayio_bitmap_set_dirty_area(destination, &area);
draw_circle(destination, x0, y0, radius, value);
}