#include "painter.h" #include "stdio.h" lp_pixel lp_rgb(uint8_t r, uint8_t g, uint8_t b) { return (lp_pixel){r, g, b}; } lp_painter *lp_painter_create(size_t width, size_t height) { lp_painter *painter = malloc(sizeof(lp_painter)); lp_pixel *buf = malloc(width * height * sizeof(lp_pixel)); painter->buf = buf; painter->buf_length = width * height; painter->width = width; painter->height = height; return painter; } void lp_painter_free(lp_painter *painter) { if (painter) { if (painter->buf) { free(painter->buf); } free(painter); } } static inline void lp_painter_put_pixel(lp_painter *painter, lp_pixel color, size_t x, size_t y) { size_t index = y * painter->width + x; painter->buf[index] = color; } void lp_painter_fill_rect(lp_painter *painter, lp_pixel fill_color, size_t pos_x, size_t pos_y, size_t width, size_t height) { for (size_t y = pos_y; y < pos_y + height; y++) { for (size_t x = pos_x; x < pos_x + width; x++) { lp_painter_put_pixel(painter, fill_color, pos_x, pos_y); } } } void _lp_painter_line_low(lp_painter *p, lp_pixel color, int32_t x0, int32_t y0, int32_t x1, int32_t y1) { int32_t dx = x1 - x0; int32_t dy = y1 - y0; int32_t y_inc = 1; if (dy < 0) { y_inc = -1; dy = -dy; } int32_t d = dy * 2 - dx; int32_t y = y0; for (int32_t x = x0; x < x1; x++) { lp_painter_put_pixel(p, color, x, y); if (d > 0) { y += y_inc; d += 2 * (dy - dx); } else { d += 2 * dy; } } } void _lp_painter_line_high(lp_painter *p, lp_pixel color, int32_t x0, int32_t y0, int32_t x1, int32_t y1) { int32_t dx = x1 - x0; int32_t dy = y1 - y0; int32_t x_inc = 1; if (dx < 0) { x_inc = -1; dx = -dx; } int32_t d = dx * 2 - dy; int32_t x = x0; for (int32_t y = y0; y < y1; y++) { lp_painter_put_pixel(p, color, x, y); if (d > 0) { x += x_inc; d += 2 * (dx - dy); } else { d += 2 * dx; } } } void lp_painter_line(lp_painter *p, lp_pixel color, int32_t x0, int32_t y0, int32_t x1, int32_t y1) { if (abs(y1 - y0) < abs(x1 -x0)) { if (x0 > x1) { _lp_painter_line_low(p, color, x1, y1, x0, y0); } else { _lp_painter_line_low(p, color, x0, y0, x1, y1); } } else { if (y0 > y1) { _lp_painter_line_high(p, color, x1, y1, x0, y0); } else { _lp_painter_line_high(p, color, x0, y0, x1, y1); } } } void lp_painter_save_ppm(lp_painter *painter, const char *filename) { FILE *fp = fopen(filename, "w"); if (fp == NULL) { fprintf(stderr, "Failed to open file"); return; } fprintf(fp, "P6\n%zu %zu 255\n", painter->width, painter->height); for (size_t i = 0; i < painter->width * painter->height; i++) { fwrite(&painter->buf[i].r, sizeof(uint8_t), 1, fp); fwrite(&painter->buf[i].g, sizeof(uint8_t), 1, fp); fwrite(&painter->buf[i].b, sizeof(uint8_t), 1, fp); } fwrite(painter->buf, sizeof(lp_pixel), painter->width * painter->height, fp); fclose(fp); }