diff options
| -rw-r--r-- | README.md | 27 | ||||
| -rw-r--r-- | examples/ppm.c | 8 | ||||
| -rw-r--r-- | nonstd.h | 16 | ||||
| -rw-r--r-- | tests.c | 10 |
4 files changed, 44 insertions, 17 deletions
@@ -19,6 +19,7 @@ ergonomic and productive. It aims to be C99 compliant. - **Memory Arena**: Simple block-based arena allocator for bulk memory management. - **File I/O**: Helper functions to read and write entire files with a single call. - **Logging**: Simple, leveled logging with ANSI colors and timestamps. +- **Canvas & PPM**: Simple 2D drawing API with PPM (ASCII) import/export. ## Installation @@ -184,6 +185,32 @@ LOG_ERROR_MSG("Connection failed"); // LOG_LEVEL=0 (ERROR) ... 3 (DEBUG) ``` +### 7. Canvas & PPM Images + +Create simple 2D images, draw shapes, and save to PPM (ASCII) format. + +```c +// Initialize a 400x400 canvas +Canvas canvas = ppm_init(400, 400); + +// Use predefined colors or HEX/RGB macros +ppm_fill(&canvas, COLOR_HEX(0x1a1a1a)); + +// Draw basic shapes +ppm_draw_rect(&canvas, 50, 50, 100, 100, COLOR_RED); +ppm_draw_circle(&canvas, 250, 100, 40, COLOR_BLUE); +ppm_draw_line(&canvas, 200, 200, 350, 350, COLOR_GREEN); +ppm_draw_triangle(&canvas, 50, 350, 150, 350, 100, 250, COLOR_YELLOW); + +// Save to file +if (ppm_save(&canvas, "output.ppm")) { + printf("Image saved successfully!\n"); +} + +// Clean up +ppm_free(&canvas); +``` + ## Testing The project includes a test suite using `minunit`. diff --git a/examples/ppm.c b/examples/ppm.c index 95fafcf..6edd1d7 100644 --- a/examples/ppm.c +++ b/examples/ppm.c @@ -10,10 +10,10 @@ int main() { ppm_fill(&img, COLOR_HEX(0x1a1a1a)); // Draw some shapes - ppm_draw_rect(&img, 50, 50, 100, 100, CLR_RED); - ppm_draw_circle(&img, 250, 100, 40, CLR_BLUE); - ppm_draw_triangle(&img, 50, 350, 150, 350, 100, 250, CLR_YELLOW); - ppm_draw_line(&img, 200, 200, 350, 350, CLR_GREEN); + ppm_draw_rect(&img, 50, 50, 100, 100, COLOR_RED); + ppm_draw_circle(&img, 250, 100, 40, COLOR_BLUE); + ppm_draw_triangle(&img, 50, 350, 150, 350, 100, 250, COLOR_YELLOW); + ppm_draw_line(&img, 200, 200, 350, 350, COLOR_GREEN); // Random colors and macros ppm_draw_rect(&img, 200, 250, 50, 80, COLOR_RGB(255, 165, 0)); @@ -263,14 +263,14 @@ typedef struct { #define COLOR_RGB(r, g, b) ((Color){(u8)(r), (u8)(g), (u8)(b)}) #define COLOR_HEX(hex) ((Color){(u8)(((hex) >> 16) & 0xFF), (u8)(((hex) >> 8) & 0xFF), (u8)((hex) & 0xFF)}) -#define CLR_BLACK COLOR_RGB(0, 0, 0) -#define CLR_WHITE COLOR_RGB(255, 255, 255) -#define CLR_RED COLOR_RGB(255, 0, 0) -#define CLR_GREEN COLOR_RGB(0, 255, 0) -#define CLR_BLUE COLOR_RGB(0, 0, 255) -#define CLR_YELLOW COLOR_RGB(255, 255, 0) -#define CLR_MAGENTA COLOR_RGB(255, 0, 255) -#define CLR_CYAN COLOR_RGB(0, 255, 255) +#define COLOR_BLACK COLOR_RGB(0, 0, 0) +#define COLOR_WHITE COLOR_RGB(255, 255, 255) +#define COLOR_RED COLOR_RGB(255, 0, 0) +#define COLOR_GREEN COLOR_RGB(0, 255, 0) +#define COLOR_BLUE COLOR_RGB(0, 0, 255) +#define COLOR_YELLOW COLOR_RGB(255, 255, 0) +#define COLOR_MAGENTA COLOR_RGB(255, 0, 255) +#define COLOR_CYAN COLOR_RGB(0, 255, 255) NONSTD_DEF Canvas ppm_init(u32 width, u32 height); NONSTD_DEF void ppm_free(Canvas *img); @@ -974,20 +974,20 @@ MU_TEST(test_ppm_draw_helpers) { Canvas img = ppm_init(100, 100); // Test fill - ppm_fill(&img, CLR_RED); + ppm_fill(&img, COLOR_RED); Color c1 = ppm_get_pixel(&img, 0, 0); mu_assert_int_eq(255, c1.r); mu_assert_int_eq(0, c1.g); // Test rect - ppm_fill(&img, CLR_BLACK); - ppm_draw_rect(&img, 10, 10, 20, 20, CLR_WHITE); + ppm_fill(&img, COLOR_BLACK); + ppm_draw_rect(&img, 10, 10, 20, 20, COLOR_WHITE); mu_assert_int_eq(255, ppm_get_pixel(&img, 10, 10).r); mu_assert_int_eq(0, ppm_get_pixel(&img, 15, 15).r); // Inside should be black // Test line - ppm_fill(&img, CLR_BLACK); - ppm_draw_line(&img, 0, 0, 10, 10, CLR_GREEN); + ppm_fill(&img, COLOR_BLACK); + ppm_draw_line(&img, 0, 0, 10, 10, COLOR_GREEN); mu_assert_int_eq(255, ppm_get_pixel(&img, 5, 5).g); // Test hexagon/color macros |
