diff options
| author | Scott Shawcroft <scott@adafruit.com> | 2021-03-12 16:50:39 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-12 16:50:39 -0800 |
| commit | b413535ee14a5e7ce15eba816d3d985de3dbc6c2 (patch) | |
| tree | 10c0fcc106eaccf8f67cbcf98d5461d9d8deaa7b /shared-module/bitmaptools/__init__.c | |
| parent | 1b106de4e0d3227c427c9086ab5215566a7b211d (diff) | |
| parent | a9afa0d9d4c66cda8fe7e6c1a72765e704e94985 (diff) | |
Merge pull request #4376 from kmatch98/displayio_bitmap
add fill_region and draw_line to bitmap_tools
Diffstat (limited to 'shared-module/bitmaptools/__init__.c')
| -rw-r--r-- | shared-module/bitmaptools/__init__.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/shared-module/bitmaptools/__init__.c b/shared-module/bitmaptools/__init__.c index 7dc4024ef..6f168b555 100644 --- a/shared-module/bitmaptools/__init__.c +++ b/shared-module/bitmaptools/__init__.c @@ -26,10 +26,12 @@ #include "shared-bindings/displayio/Bitmap.h" +#include "shared-module/displayio/Bitmap.h" #include "py/runtime.h" #include "math.h" +#include "stdlib.h" 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, @@ -172,3 +174,165 @@ void common_hal_bitmaptools_rotozoom(displayio_bitmap_t *self, int16_t ox, int16 rowv += dvCol; } } + +int16_t constrain(int16_t input, int16_t min, int16_t max) { + // constrain the input between the min and max values + if (input < min) { + return min; + } + if (input > max) { + return max; + } + return input; +} + +void common_hal_bitmaptools_fill_region(displayio_bitmap_t *destination, + int16_t x1, int16_t y1, + int16_t x2, int16_t y2, + uint32_t value) { + // writes the value (a bitmap color index) into a bitmap in the specified rectangular region + // + // input checks should ensure that x1 < x2 and y1 < y2 and are within the bitmap region + + if (destination->read_only) { + mp_raise_RuntimeError(translate("Read-only object")); + } + + // Ensure x1 < x2 and y1 < y2 + if (x1 > x2) { + int16_t temp=x2; + x2=x1; + x1=temp; + } + if (y1 > y2) { + int16_t temp=y2; + y2=y1; + y1=temp; + } + + // constrain to bitmap dimensions + x1 = constrain(x1, 0, destination->width); + x2 = constrain(x2, 0, destination->width); + y1 = constrain(y1, 0, destination->height); + y2 = constrain(y2, 0, destination->height); + + // update the dirty rectangle + displayio_bitmap_set_dirty_area(destination, x1, y1, x2, y2); + + int16_t x, y; + for (x = x1; x < x2; x++) { + for (y = y1; y < y2; y++ ) { + displayio_bitmap_write_pixel(destination, x, y, value); + } + } +} + +void common_hal_bitmaptools_draw_line(displayio_bitmap_t *destination, + int16_t x0, int16_t y0, + int16_t x1, int16_t y1, + uint32_t value) { + + if (destination->read_only) { + mp_raise_RuntimeError(translate("Read-only object")); + } + + // + // adapted from Adafruit_CircuitPython_Display_Shapes.Polygon._line + // + + // update the dirty rectangle + int16_t xbb0, xbb1, ybb0, ybb1; + if (x0 < x1) { + xbb0 = x0; + xbb1 = x1 + 1; + } else { + xbb0 = x1; + xbb1 = x0 + 1; + } + if (y0 < y1) { + ybb0 = y0; + ybb1 = y1 + 1; + } else { + ybb0 = y1; + ybb1 = y0 + 1; + } + + xbb0 = constrain(xbb0, 0, destination->width); + xbb1 = constrain(xbb1, 0, destination->width); + ybb0 = constrain(ybb0, 0, destination->height); + ybb1 = constrain(ybb1, 0, destination->height); + + displayio_bitmap_set_dirty_area(destination, xbb0, ybb0, xbb1, ybb1); + + int16_t temp, x, y; + + if (x0 == x1) { // vertical line + if (y0 > y1) { // ensure y1 > y0 + temp = y0; + y0 = y1; + y1 = temp; + } + for (y = y0; y < (y1 + 1); y++) { // write a horizontal line + displayio_bitmap_write_pixel(destination, x0, y, value); + } + } + else if (y0 == y1) { // horizontal line + if (x0 > x1) { // ensure y1 > y0 + temp = x0; + x0 = x1; + x1 = temp; + } + for (x = x0; x < (x1 + 1); x++) { // write a horizontal line + displayio_bitmap_write_pixel(destination, x, y0, value); + } + } + else { + bool steep; + steep = ( abs(y1 - y0) > abs(x1 - x0) ); + + if ( steep ) { // flip x0<->y0 and x1<->y1 + temp = x0; + x0 = y0; + y0 = temp; + temp = x1; + x1 = y1; + y1 = temp; + } + + if (x0 > x1) { // flip x0<->x1 and y0<->y1 + temp = x0; + x0 = x1; + x1 = temp; + temp = y0; + y0 = y1; + y1 = temp; + } + + int16_t dx, dy, ystep; + dx = x1 - x0; + dy = abs(y1 - y0); + + float err = dx / 2; + + if (y0 < y1) { + ystep = 1; + } + else { + ystep = -1; + } + + for (x = x0; x < (x1 + 1); x++) { + if (steep) { + displayio_bitmap_write_pixel(destination, y0, x, value); + } + else { + displayio_bitmap_write_pixel(destination, x, y0, value); + } + err -= dy; + if (err < 0) { + y0 += ystep; + err += dx; + } + } + } +} |
