From b6eddc99f5187d933e83114d7cf75ba1c5715703 Mon Sep 17 00:00:00 2001 From: AbdelrahmanHafez Date: Mon, 29 Aug 2022 12:03:42 +0200 Subject: [PATCH 1/2] Auto Formatting --- olive.c | 93 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 31 deletions(-) diff --git a/olive.c b/olive.c index 92dc16e..5c93ea3 100644 --- a/olive.c +++ b/olive.c @@ -7,14 +7,26 @@ typedef int Errno; -#define return_defer(value) do { result = (value); goto defer; } while (0) -#define OLIVEC_SWAP(T, a, b) do { T t = a; a = b; b = t; } while (0) +#define return_defer(value) \ + do \ + { \ + result = (value); \ + goto defer; \ + } while (0) +#define OLIVEC_SWAP(T, a, b) \ + do \ + { \ + T t = a; \ + a = b; \ + b = t; \ + } while (0) #define OLIVEC_SIGN(T, x) ((T)((x) > 0) - (T)((x) < 0)) -#define OLIVEC_ABS(T, x) (OLIVEC_SIGN(T, x)*(x)) +#define OLIVEC_ABS(T, x) (OLIVEC_SIGN(T, x) * (x)) void olivec_fill(uint32_t *pixels, size_t width, size_t height, uint32_t color) { - for (size_t i = 0; i < width*height; ++i) { + for (size_t i = 0; i < width * height; ++i) + { pixels[i] = color; } } @@ -26,25 +38,30 @@ Errno olivec_save_to_ppm_file(uint32_t *pixels, size_t width, size_t height, con { f = fopen(file_path, "wb"); - if (f == NULL) return_defer(errno); + if (f == NULL) + return_defer(errno); fprintf(f, "P6\n%zu %zu 255\n", width, height); - if (ferror(f)) return_defer(errno); + if (ferror(f)) + return_defer(errno); - for (size_t i = 0; i < width*height; ++i) { + for (size_t i = 0; i < width * height; ++i) + { uint32_t pixel = pixels[i]; uint8_t bytes[3] = { - (pixel>>(8*0))&0xFF, - (pixel>>(8*1))&0xFF, - (pixel>>(8*2))&0xFF, + (pixel >> (8 * 0)) & 0xFF, + (pixel >> (8 * 1)) & 0xFF, + (pixel >> (8 * 2)) & 0xFF, }; fwrite(bytes, sizeof(bytes), 1, f); - if (ferror(f)) return_defer(errno); + if (ferror(f)) + return_defer(errno); } } defer: - if (f) fclose(f); + if (f) + fclose(f); return result; } @@ -56,17 +73,23 @@ void olivec_fill_rect(uint32_t *pixels, size_t pixels_width, size_t pixels_heigh int x1, int y1, int w, int h, uint32_t color) { - int x2 = x1 + OLIVEC_SIGN(int, w)*(OLIVEC_ABS(int, w) - 1); - if (x1 > x2) OLIVEC_SWAP(int, x1, x2); - int y2 = y1 + OLIVEC_SIGN(int, h)*(OLIVEC_ABS(int, h) - 1); - if (y1 > y2) OLIVEC_SWAP(int, y1, y2); - - for (int y = y1; y <= y2; ++y) { + int x2 = x1 + OLIVEC_SIGN(int, w) * (OLIVEC_ABS(int, w) - 1); + if (x1 > x2) + OLIVEC_SWAP(int, x1, x2); + int y2 = y1 + OLIVEC_SIGN(int, h) * (OLIVEC_ABS(int, h) - 1); + if (y1 > y2) + OLIVEC_SWAP(int, y1, y2); + + for (int y = y1; y <= y2; ++y) + { // TODO: move boundary checks out of the loops in olivec_fill_rect - if (0 <= y && y < (int) pixels_height) { - for (int x = x1; x <= x2; ++x) { - if (0 <= x && x < (int) pixels_width) { - pixels[y*pixels_width + x] = color; + if (0 <= y && y < (int)pixels_height) + { + for (int x = x1; x <= x2; ++x) + { + if (0 <= x && x < (int)pixels_width) + { + pixels[y * pixels_width + x] = color; } } } @@ -81,25 +104,33 @@ void olivec_fill_circle(uint32_t *pixels, size_t pixels_width, size_t pixels_hei int cx, int cy, int r, uint32_t color) { - if (r == 0) return; + if (r == 0) + return; int x1 = cx - r; int x2 = cx + r; - if (x1 > x2) OLIVEC_SWAP(int, x1, x2); + if (x1 > x2) + OLIVEC_SWAP(int, x1, x2); int y1 = cy - r; int y2 = cy + r; - if (y1 > y2) OLIVEC_SWAP(int, y1, y2); + if (y1 > y2) + OLIVEC_SWAP(int, y1, y2); - for (int y = y1; y <= y2; ++y) { + for (int y = y1; y <= y2; ++y) + { // TODO: move boundary checks out of the loops in olivec_fill_circle - if (0 <= y && y < (int) pixels_height) { - for (int x = x1; x <= x2; ++x) { - if (0 <= x && x < (int) pixels_width) { + if (0 <= y && y < (int)pixels_height) + { + for (int x = x1; x <= x2; ++x) + { + if (0 <= x && x < (int)pixels_width) + { int dx = x - cx; int dy = y - cy; - if (dx*dx + dy*dy <= r*r) { - pixels[y*pixels_width + x] = color; + if (dx * dx + dy * dy <= r * r) + { + pixels[y * pixels_width + x] = color; } } } From b12efe82d94af4f3279156558e2136057aa37798 Mon Sep 17 00:00:00 2001 From: AbdelrahmanHafez Date: Mon, 29 Aug 2022 12:05:36 +0200 Subject: [PATCH 2/2] Bresenham integer line algorithm --- olive.c | 77 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/olive.c b/olive.c index 5c93ea3..5308f73 100644 --- a/olive.c +++ b/olive.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include typedef int Errno; @@ -138,40 +140,59 @@ void olivec_fill_circle(uint32_t *pixels, size_t pixels_width, size_t pixels_hei } } +void olivec_draw_pixel(uint32_t *pixels, size_t pixels_width, size_t pixels_height, int x, int y, uint32_t color) +{ + if (x < 0 || x >= (int)pixels_width || y < 0 || y >= (int)pixels_height) + return; + + pixels[y * pixels_width + x] = color; +} + // TODO: lines with different thicness void olivec_draw_line(uint32_t *pixels, size_t pixels_width, size_t pixels_height, int x1, int y1, int x2, int y2, uint32_t color) { - // TODO: fix the olivec_draw_line stairs + bool steep = abs(y2 - y1) > abs(x2 - x1); + + if (steep) + { + OLIVEC_SWAP(int, x1, y1); + OLIVEC_SWAP(int, x2, y2); + } + + if (x1 > x2) + { + OLIVEC_SWAP(int, x1, x2); + OLIVEC_SWAP(int, y1, y2); + } + + int deltay; + if (y1 > y2) + deltay = -1; + else + deltay = 1; + int dx = x2 - x1; - int dy = y2 - y1; - - if (dx != 0) { - int c = y1 - dy*x1/dx; - - if (x1 > x2) OLIVEC_SWAP(int, x1, x2); - for (int x = x1; x <= x2; ++x) { - if (0 <= x && x < (int) pixels_width) { - int sy1 = dy*x/dx + c; - int sy2 = dy*(x + 1)/dx + c; - if (sy1 > sy2) OLIVEC_SWAP(int, sy1, sy2); - for (int y = sy1; y <= sy2; ++y) { - if (0 <= y && y < (int) pixels_height) { - pixels[y*pixels_width + x] = color; - } - } - } - } - } else { - int x = x1; - if (0 <= x && x < (int) pixels_width) { - if (y1 > y2) OLIVEC_SWAP(int, y1, y2); - for (int y = y1; y <= y2; ++y) { - if (0 <= y && y < (int) pixels_height) { - pixels[y*pixels_width + x] = color; - } - } + int dy = abs(y2 - y1); + int y = y1; + int error = 0; + + for (int x = x1; x < x2; x++) + { + if (x < 0 || x >= (int)pixels_width) + continue; + + if (steep) + olivec_draw_pixel(pixels, pixels_width, pixels_height, y, x, color); + else + olivec_draw_pixel(pixels, pixels_width, pixels_height, x, y, color); + + error += dy; + if (2 * error >= dx) + { + y = y + deltay; + error -= dx; } } }