diff --git a/src/util/image.c b/src/util/image.c index d68491718..440026ba0 100644 --- a/src/util/image.c +++ b/src/util/image.c @@ -705,6 +705,9 @@ static void _drawCircle2x2(struct mPainter* painter, int x, int y, uint32_t colo } void mPainterDrawCircle(struct mPainter* painter, int x, int y, int diameter) { + if (diameter < 1) { + return; + } int radius = diameter / 2; int offset = (diameter ^ 1) & 1; int stroke = painter->strokeWidth; @@ -740,7 +743,7 @@ void mPainterDrawCircle(struct mPainter* painter, int x, int y, int diameter) { mPainterDrawPixel(painter, x + i, y + radius, painter->strokeColor); } if (painter->fill) { - for (i = i; i < y1 + 1; ++i) { + for (i = 1; i < y1 + 1; ++i) { mPainterDrawPixel(painter, x + radius, y + radius - i, painter->fillColor); mPainterDrawPixel(painter, x + radius, y + radius + i, painter->fillColor); mPainterDrawPixel(painter, x + radius - i, y + radius, painter->fillColor); diff --git a/src/util/test/image.c b/src/util/test/image.c index eed41a913..a27e53d5c 100644 --- a/src/util/test/image.c +++ b/src/util/test/image.c @@ -1300,6 +1300,24 @@ M_TEST_DEFINE(painterFillRectangleBlend) { mImageDestroy(image); } +M_TEST_DEFINE(painterFillRectangleInvalid) { + struct mImage* image; + struct mPainter painter; + + image = mImageCreate(4, 4, mCOLOR_XRGB8); + mPainterInit(&painter, image); + painter.blend = false; + painter.fill = true; + painter.strokeWidth = 0; + painter.fillColor = 0xFF0000FF; + mPainterDrawRectangle(&painter, 1, 1, -1, -1); + COMPARE4X(0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000); + mImageDestroy(image); +} + M_TEST_DEFINE(painterStrokeRectangle) { struct mImage* image; struct mPainter painter; @@ -1565,6 +1583,25 @@ M_TEST_DEFINE(painterStrokeRectangleBlend) { 0x400000FF, 0x40FF0000, 0x6F91006D, 0x40FF0000, 0x400000FF, 0x6F91006D, 0x400000FF, 0x40FF0000, 0x00000000, 0x40FF0000, 0x40FF0000, 0x40FF0000); + mImageDestroy(image); +} + +M_TEST_DEFINE(painterStrokeRectangleInvalid) { + struct mImage* image; + struct mPainter painter; + + image = mImageCreate(4, 4, mCOLOR_XRGB8); + mPainterInit(&painter, image); + painter.blend = false; + painter.fill = false; + painter.strokeWidth = 1; + painter.strokeColor = 0xFF0000FF; + mPainterDrawRectangle(&painter, 1, 1, -1, -1); + COMPARE4X(0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000); + mImageDestroy(image); } M_TEST_DEFINE(painterDrawRectangle) { @@ -1876,6 +1913,7 @@ M_TEST_DEFINE(painterDrawCircleArea) { } float area = i * i; assert_float_equal(filled / area, M_PI / 4, 0.12); + mImageDestroy(image); } } @@ -1905,10 +1943,10 @@ M_TEST_DEFINE(painterDrawCircleCircumference) { } } assert_float_equal(filled / (float) i, M_PI, M_PI * 0.11); + mImageDestroy(image); } } - M_TEST_DEFINE(painterDrawCircleOffset) { struct mImage* image; struct mPainter painter; @@ -1935,9 +1973,71 @@ M_TEST_DEFINE(painterDrawCircleOffset) { assert_int_equal(color, mImageGetPixel(image, x + i, y + i)); } } + mImageDestroy(image); } } +M_TEST_DEFINE(painterDrawCircleBlend) { + struct mImage* image; + struct mPainter painter; + + int i, j; + for (i = 1; i < 10; ++i) { + for (j = 0; j < i / 2 + 1; ++j) { + image = mImageCreate(i, i, mCOLOR_ARGB8); + mPainterInit(&painter, image); + painter.blend = true; + painter.fill = true; + painter.strokeWidth = j; + painter.fillColor = 0x8000FF00; + painter.strokeColor = 0x800000FF; + mPainterDrawCircle(&painter, 0, 0, i); + + int x, y; + for (y = 0; y < i; ++y) { + for (x = 0; x < i; ++x) { + uint32_t color = mImageGetPixel(image, x, y); + if (color != painter.strokeColor && color != painter.fillColor) { + assert_int_equal(color, 0); + } + } + } + mImageDestroy(image); + } + } +} + +M_TEST_DEFINE(painterDrawCircleInvalid) { + struct mImage* image; + struct mPainter painter; + + image = mImageCreate(4, 4, mCOLOR_XRGB8); + mPainterInit(&painter, image); + painter.blend = false; + painter.fill = true; + painter.strokeWidth = 0; + painter.fillColor = 0xFF0000FF; + mPainterDrawCircle(&painter, 2, 2, -1); + COMPARE4X(0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00); + mImageDestroy(image); + + image = mImageCreate(4, 4, mCOLOR_XRGB8); + mPainterInit(&painter, image); + painter.blend = false; + painter.fill = false; + painter.strokeWidth = 1; + painter.strokeColor = 0xFF0000FF; + mPainterDrawCircle(&painter, 2, 2, -1); + COMPARE4X(0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00); + mImageDestroy(image); +} + #undef COMPARE3X #undef COMPARE3 #undef COMPARE4X @@ -1969,9 +2069,11 @@ M_TEST_SUITE_DEFINE(Image, cmocka_unit_test(blitBoundaries), cmocka_unit_test(painterFillRectangle), cmocka_unit_test(painterFillRectangleBlend), + cmocka_unit_test(painterFillRectangleInvalid), cmocka_unit_test(painterStrokeRectangle), cmocka_unit_test(painterStrokeRectangleWidth), cmocka_unit_test(painterStrokeRectangleBlend), + cmocka_unit_test(painterStrokeRectangleInvalid), cmocka_unit_test(painterDrawRectangle), cmocka_unit_test(painterDrawLineOctants), cmocka_unit_test(painterDrawLineWidth), @@ -1979,4 +2081,6 @@ M_TEST_SUITE_DEFINE(Image, cmocka_unit_test(painterDrawCircleArea), cmocka_unit_test(painterDrawCircleCircumference), cmocka_unit_test(painterDrawCircleOffset), + cmocka_unit_test(painterDrawCircleBlend), + cmocka_unit_test(painterDrawCircleInvalid), )