|
diff --git a/README.md b/README.md
|
| ... |
| 19 |
- **Memory Arena**: Simple block-based arena allocator for bulk memory management. |
19 |
- **Memory Arena**: Simple block-based arena allocator for bulk memory management. |
| 20 |
- **File I/O**: Helper functions to read and write entire files with a single call. |
20 |
- **File I/O**: Helper functions to read and write entire files with a single call. |
| 21 |
- **Logging**: Simple, leveled logging with ANSI colors and timestamps. |
21 |
- **Logging**: Simple, leveled logging with ANSI colors and timestamps. |
|
|
22 |
- **Canvas & PPM**: Simple 2D drawing API with PPM (ASCII) import/export. |
| 22 |
|
23 |
|
| 23 |
## Installation |
24 |
## Installation |
| 24 |
|
25 |
|
| ... |
| 182 |
|
183 |
|
| 183 |
// Environment variable override supported: |
184 |
// Environment variable override supported: |
| 184 |
// LOG_LEVEL=0 (ERROR) ... 3 (DEBUG) |
185 |
// LOG_LEVEL=0 (ERROR) ... 3 (DEBUG) |
|
|
186 |
``` |
|
|
187 |
|
|
|
188 |
### 7. Canvas & PPM Images |
|
|
189 |
|
|
|
190 |
Create simple 2D images, draw shapes, and save to PPM (ASCII) format. |
|
|
191 |
|
|
|
192 |
```c |
|
|
193 |
// Initialize a 400x400 canvas |
|
|
194 |
Canvas canvas = ppm_init(400, 400); |
|
|
195 |
|
|
|
196 |
// Use predefined colors or HEX/RGB macros |
|
|
197 |
ppm_fill(&canvas, COLOR_HEX(0x1a1a1a)); |
|
|
198 |
|
|
|
199 |
// Draw basic shapes |
|
|
200 |
ppm_draw_rect(&canvas, 50, 50, 100, 100, COLOR_RED); |
|
|
201 |
ppm_draw_circle(&canvas, 250, 100, 40, COLOR_BLUE); |
|
|
202 |
ppm_draw_line(&canvas, 200, 200, 350, 350, COLOR_GREEN); |
|
|
203 |
ppm_draw_triangle(&canvas, 50, 350, 150, 350, 100, 250, COLOR_YELLOW); |
|
|
204 |
|
|
|
205 |
// Save to file |
|
|
206 |
if (ppm_save(&canvas, "output.ppm")) { |
|
|
207 |
printf("Image saved successfully!\n"); |
|
|
208 |
} |
|
|
209 |
|
|
|
210 |
// Clean up |
|
|
211 |
ppm_free(&canvas); |
| 185 |
``` |
212 |
``` |
| 186 |
|
213 |
|
| 187 |
## Testing |
214 |
## Testing |
| ... |
|
diff --git a/examples/ppm.c b/examples/ppm.c
|
| ... |
| 10 |
ppm_fill(&img, COLOR_HEX(0x1a1a1a)); |
10 |
ppm_fill(&img, COLOR_HEX(0x1a1a1a)); |
| 11 |
|
11 |
|
| 12 |
// Draw some shapes |
12 |
// Draw some shapes |
| 13 |
ppm_draw_rect(&img, 50, 50, 100, 100, CLR_RED); |
13 |
ppm_draw_rect(&img, 50, 50, 100, 100, COLOR_RED); |
| 14 |
ppm_draw_circle(&img, 250, 100, 40, CLR_BLUE); |
14 |
ppm_draw_circle(&img, 250, 100, 40, COLOR_BLUE); |
| 15 |
ppm_draw_triangle(&img, 50, 350, 150, 350, 100, 250, CLR_YELLOW); |
15 |
ppm_draw_triangle(&img, 50, 350, 150, 350, 100, 250, COLOR_YELLOW); |
| 16 |
ppm_draw_line(&img, 200, 200, 350, 350, CLR_GREEN); |
16 |
ppm_draw_line(&img, 200, 200, 350, 350, COLOR_GREEN); |
| 17 |
|
17 |
|
| 18 |
// Random colors and macros |
18 |
// Random colors and macros |
| 19 |
ppm_draw_rect(&img, 200, 250, 50, 80, COLOR_RGB(255, 165, 0)); |
19 |
ppm_draw_rect(&img, 200, 250, 50, 80, COLOR_RGB(255, 165, 0)); |
| ... |
|
diff --git a/nonstd.h b/nonstd.h
|
| ... |
| 263 |
#define COLOR_RGB(r, g, b) ((Color){(u8)(r), (u8)(g), (u8)(b)}) |
263 |
#define COLOR_RGB(r, g, b) ((Color){(u8)(r), (u8)(g), (u8)(b)}) |
| 264 |
#define COLOR_HEX(hex) ((Color){(u8)(((hex) >> 16) & 0xFF), (u8)(((hex) >> 8) & 0xFF), (u8)((hex) & 0xFF)}) |
264 |
#define COLOR_HEX(hex) ((Color){(u8)(((hex) >> 16) & 0xFF), (u8)(((hex) >> 8) & 0xFF), (u8)((hex) & 0xFF)}) |
| 265 |
|
265 |
|
| 266 |
#define CLR_BLACK COLOR_RGB(0, 0, 0) |
266 |
#define COLOR_BLACK COLOR_RGB(0, 0, 0) |
| 267 |
#define CLR_WHITE COLOR_RGB(255, 255, 255) |
267 |
#define COLOR_WHITE COLOR_RGB(255, 255, 255) |
| 268 |
#define CLR_RED COLOR_RGB(255, 0, 0) |
268 |
#define COLOR_RED COLOR_RGB(255, 0, 0) |
| 269 |
#define CLR_GREEN COLOR_RGB(0, 255, 0) |
269 |
#define COLOR_GREEN COLOR_RGB(0, 255, 0) |
| 270 |
#define CLR_BLUE COLOR_RGB(0, 0, 255) |
270 |
#define COLOR_BLUE COLOR_RGB(0, 0, 255) |
| 271 |
#define CLR_YELLOW COLOR_RGB(255, 255, 0) |
271 |
#define COLOR_YELLOW COLOR_RGB(255, 255, 0) |
| 272 |
#define CLR_MAGENTA COLOR_RGB(255, 0, 255) |
272 |
#define COLOR_MAGENTA COLOR_RGB(255, 0, 255) |
| 273 |
#define CLR_CYAN COLOR_RGB(0, 255, 255) |
273 |
#define COLOR_CYAN COLOR_RGB(0, 255, 255) |
| 274 |
|
274 |
|
| 275 |
NONSTD_DEF Canvas ppm_init(u32 width, u32 height); |
275 |
NONSTD_DEF Canvas ppm_init(u32 width, u32 height); |
| 276 |
NONSTD_DEF void ppm_free(Canvas *img); |
276 |
NONSTD_DEF void ppm_free(Canvas *img); |
| ... |
|
diff --git a/tests.c b/tests.c
|
| ... |
| 974 |
Canvas img = ppm_init(100, 100); |
974 |
Canvas img = ppm_init(100, 100); |
| 975 |
|
975 |
|
| 976 |
// Test fill |
976 |
// Test fill |
| 977 |
ppm_fill(&img, CLR_RED); |
977 |
ppm_fill(&img, COLOR_RED); |
| 978 |
Color c1 = ppm_get_pixel(&img, 0, 0); |
978 |
Color c1 = ppm_get_pixel(&img, 0, 0); |
| 979 |
mu_assert_int_eq(255, c1.r); |
979 |
mu_assert_int_eq(255, c1.r); |
| 980 |
mu_assert_int_eq(0, c1.g); |
980 |
mu_assert_int_eq(0, c1.g); |
| 981 |
|
981 |
|
| 982 |
// Test rect |
982 |
// Test rect |
| 983 |
ppm_fill(&img, CLR_BLACK); |
983 |
ppm_fill(&img, COLOR_BLACK); |
| 984 |
ppm_draw_rect(&img, 10, 10, 20, 20, CLR_WHITE); |
984 |
ppm_draw_rect(&img, 10, 10, 20, 20, COLOR_WHITE); |
| 985 |
mu_assert_int_eq(255, ppm_get_pixel(&img, 10, 10).r); |
985 |
mu_assert_int_eq(255, ppm_get_pixel(&img, 10, 10).r); |
| 986 |
mu_assert_int_eq(0, ppm_get_pixel(&img, 15, 15).r); // Inside should be black |
986 |
mu_assert_int_eq(0, ppm_get_pixel(&img, 15, 15).r); // Inside should be black |
| 987 |
|
987 |
|
| 988 |
// Test line |
988 |
// Test line |
| 989 |
ppm_fill(&img, CLR_BLACK); |
989 |
ppm_fill(&img, COLOR_BLACK); |
| 990 |
ppm_draw_line(&img, 0, 0, 10, 10, CLR_GREEN); |
990 |
ppm_draw_line(&img, 0, 0, 10, 10, COLOR_GREEN); |
| 991 |
mu_assert_int_eq(255, ppm_get_pixel(&img, 5, 5).g); |
991 |
mu_assert_int_eq(255, ppm_get_pixel(&img, 5, 5).g); |
| 992 |
|
992 |
|
| 993 |
// Test hexagon/color macros |
993 |
// Test hexagon/color macros |
| ... |