diff --git a/src/Draw.c b/src/Draw.c index ba33a2d..bdc53fd 100644 --- a/src/Draw.c +++ b/src/Draw.c @@ -729,24 +729,67 @@ int Draw_GetFlip(DrawImg img) { return image->flip; } +///////////////////////////// +// Draw_SetPixel +// Draw_AddPixel +// +// +DrawImg Draw_SetPixel(DrawImg img, const int x, const int y, const ColorRgba color) { + DrawImage image = img; + if (x < 0 || y < 0) { + return img; + } + if (x >= image->w || y >= image->h) { + return img; + } + const int offset = (x + y * image->w) * 4; + image->data[offset + 0] = color[0]; + image->data[offset + 1] = color[1]; + image->data[offset + 2] = color[2]; + image->data[offset + 3] = color[3]; + return img; +} +DrawImg Draw_AddPixel(DrawImg img, const int x, const int y, const ColorRgba color, const float factor) { + const float alpha = factor * ((float)color[3] / 255); + if (alpha <= 0) { + return img; + } + if (alpha >= 255) { + Draw_SetPixel(img, x, y, color); + return img; + } + DrawImage image = img; + if (x < 0 || y < 0) { + return img; + } + if (x >= image->w || y >= image->h) { + return img; + } + + const uint8_t a = (uint8_t)(alpha * 255); + const uint8_t r = (int)((float)color[0] * alpha); + const uint8_t g = (int)((float)color[1] * alpha); + const uint8_t b = (int)((float)color[2] * alpha); + + const int offset = (x + y * image->w) * 4; + image->data[offset + 0] = SumClamp_uint8(image->data[offset + 0] * (1 - alpha), r); + image->data[offset + 1] = SumClamp_uint8(image->data[offset + 1] * (1 - alpha), g); + image->data[offset + 2] = SumClamp_uint8(image->data[offset + 2] * (1 - alpha), b); + image->data[offset + 3] = SumClamp_uint8(image->data[offset + 3], a); + return img; +} + ///////////////////////////// // Draw_DrawBoxFilled // // DrawImg Draw_DrawBoxFilled(DrawImg img, const int x1, const int y1, const int x2, const int y2, const ColorRgba color) { - DrawImage image = img; - for (int y = y1; y < y2; y++) { for (int x = x1; x < x2; x++) { - const int offset = (x + y * image->w) * 4; - image->data[offset + 0] = color[0]; - image->data[offset + 1] = color[1]; - image->data[offset + 2] = color[2]; - image->data[offset + 3] = color[3]; + Draw_SetPixel(img, x, y, color); } } - - return (img); + return img; } ///////////////////////////// @@ -754,36 +797,51 @@ DrawImg Draw_DrawBoxFilled(DrawImg img, const int x1, const int y1, const int x2 // // DrawImg Draw_DrawBox(DrawImg img, const int x1, const int y1, const int x2, const int y2, const ColorRgba color) { - DrawImage image = img; - for (int x = x1; x < x2; x++) { - const int offset1 = (x + y1 * image->w) * 4; - image->data[offset1 + 0] = color[0]; - image->data[offset1 + 1] = color[1]; - image->data[offset1 + 2] = color[2]; - image->data[offset1 + 3] = color[3]; - const int offset2 = (x + (y2 - 1) * image->w) * 4; - image->data[offset2 + 0] = color[0]; - image->data[offset2 + 1] = color[1]; - image->data[offset2 + 2] = color[2]; - image->data[offset2 + 3] = color[3]; + Draw_SetPixel(img, x, y1, color); + Draw_SetPixel(img, x, y2 - 1, color); } for (int y = y1 + 1; y < y2 - 1; y++) { - const int offset1 = (x1 + y * image->w) * 4; - image->data[offset1 + 0] = color[0]; - image->data[offset1 + 1] = color[1]; - image->data[offset1 + 2] = color[2]; - image->data[offset1 + 3] = color[3]; - const int offset2 = ((x2 - 1) + y * image->w) * 4; - image->data[offset2 + 0] = color[0]; - image->data[offset2 + 1] = color[1]; - image->data[offset2 + 2] = color[2]; - image->data[offset2 + 3] = color[3]; + Draw_SetPixel(img, x1, y, color); + Draw_SetPixel(img, x2 - 1, y, color); } - return (img); } +///////////////////////////// +// Draw_DrawCircle +// +// +DrawImg Draw_DrawCircle(DrawImg img, int centerX, int centerY, int radius, int innerRadius, const ColorRgba color) { + for (int y = -centerY; y < centerY; y++) { + for (int x = -centerX; x < centerX; x++) { + const float dist = sqrtf((float)(x * x + y * y)); + if (dist <= (float)radius) { + const float delta = (float)radius - dist; + if (delta > 1.0f) { + // In + const float innerDelta = (float)innerRadius - dist; + if (innerDelta > 1.0f) { + // In + } else if (innerDelta <= 1.0f && innerDelta >= 0.0f) { + // Edge + Draw_AddPixel(img, centerX + x, centerY + y, color, 1.0f - innerDelta); + } else { + // Out + Draw_AddPixel(img, centerX + x, centerY + y, color, 1.0f); + } + } else if (delta <= 1.0f && delta >= 0.0f) { + // Edge + Draw_AddPixel(img, centerX + x, centerY + y, color, delta); + } else { + // Out + } + } + } + } + return img; +} + ///////////////////////////// // Draw_DrawImg // diff --git a/src/Draw.h b/src/Draw.h index 1c279bd..a89adf7 100644 --- a/src/Draw.h +++ b/src/Draw.h @@ -81,6 +81,14 @@ void Draw_GetOffset(DrawImg img, int *x, int *y); void Draw_SetFlip(DrawImg img, int flip); int Draw_GetFlip(DrawImg img); +///////////////////////////// +// Draw_SetPixel +// Draw_AddPixel +// +// +DrawImg Draw_SetPixel(DrawImg img, int x, int y, const ColorRgba color); +DrawImg Draw_AddPixel(DrawImg img, int x, int y, const ColorRgba color, float factor); + ///////////////////////////// // Draw_DrawBoxFilled // @@ -93,6 +101,12 @@ DrawImg Draw_DrawBoxFilled(DrawImg img, int x1, int y1, int x2, int y2, const Co // DrawImg Draw_DrawBox(DrawImg img, int x1, int y1, int x2, int y2, const ColorRgba color); +///////////////////////////// +// Draw_DrawCircle +// +// +DrawImg Draw_DrawCircle(DrawImg img, int centerX, int centerY, int radius, int innerRadius, const ColorRgba color); + ///////////////////////////// // Draw_DrawImg // diff --git a/src/Util.c b/src/Util.c index a4b0fb5..c97172c 100644 --- a/src/Util.c +++ b/src/Util.c @@ -26,6 +26,14 @@ int MaximumInt(int i0, int i1) { return i0; } +uint8_t SumClamp_uint8(const uint8_t a, const uint8_t b) { + const uint16_t sum = a + b; + if (sum > 255) { + return 255; + } + return sum; +} + ///////////////////////////// // Rect // diff --git a/src/Util.h b/src/Util.h index 57f24b8..459bbd3 100644 --- a/src/Util.h +++ b/src/Util.h @@ -5,6 +5,7 @@ #include #include +#include #define Pi (3.1415925f) @@ -18,6 +19,8 @@ int MinimumInt(int i0, int i1); int MaximumInt(int i0, int i1); +uint8_t SumClamp_uint8(const uint8_t a, const uint8_t b); + ///////////////////////////// // Rect //