From d97adeff491974e9c914f6039fbbe8e011589516 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Tue, 14 Jan 2020 22:16:19 +0100 Subject: [PATCH] Better drawAnnulusSector --- .../thirdparty/libopenui/src/bitmapbuffer.cpp | 139 +++++++++++------- 1 file changed, 83 insertions(+), 56 deletions(-) diff --git a/radio/src/thirdparty/libopenui/src/bitmapbuffer.cpp b/radio/src/thirdparty/libopenui/src/bitmapbuffer.cpp index 5a1b12786..34baf7194 100755 --- a/radio/src/thirdparty/libopenui/src/bitmapbuffer.cpp +++ b/radio/src/thirdparty/libopenui/src/bitmapbuffer.cpp @@ -263,58 +263,89 @@ void BitmapBuffer::drawFilledCircle(coord_t x, coord_t y, coord_t radius, LcdFla } } -bool evalSlopes(int * slopes, int startAngle, int endAngle) -{ - if (startAngle == 0) { - slopes[1] = 100000; - slopes[2] = -100000; - } - else { - float angle1 = float(startAngle) * (M_PI / 180.0f); - if (startAngle >= 180) { - slopes[1] = -100000; - slopes[2] = cosf(angle1) * 100 / sinf(angle1); - } - else if (startAngle < 0 && endAngle > 0) { - slopes[1] = 100000; - slopes[2] = - cosf(angle1) * 100 / sinf(angle1); - } - else { - slopes[1] = cosf(angle1) * 100 / sinf(angle1); - slopes[2] = -100000; - } - } +class Slope { + public: + explicit Slope(int angle) { + if (angle < 0) + angle += 360; + if (angle >= 360) + angle %= 360; + float radians = float(angle) * (M_PI / 180.0f); + if (angle == 0) { + left = false; + value = 100000; + } + else if (angle > 180) { + left = true; + value = -(cosf(radians) * 100 / sinf(radians)); + } + else { + left = false; + value = (cosf(radians) * 100 / sinf(radians)); + } - if (endAngle == 360) { - slopes[0] = -100000; - slopes[3] = 100000; - } - else { - float angle2 = float(endAngle) * (M_PI / 180.0f); - if (endAngle >= 180) { - slopes[0] = -100000; - slopes[3] = -cosf(angle2) * 100 / sinf(angle2); + // TRACE("angle=%d left=%d slope=%d", angle, left, value); } - else if (startAngle < 0) { - slopes[0] = cosf(angle2) * 100 / sinf(angle2); - slopes[3] = 100000; - } - else { - slopes[0] = cosf(angle2) * 100 / sinf(angle2); - slopes[3] = -100000; - } - } - return true; -} + Slope(bool left, int value): + left(left), + value(value) + { + } + + bool isBetween(const Slope & start, const Slope & end) const + { + if (left) { + if (start.left) { + if (end.left) + return end.value > start.value ? (value <= end.value && value >= start.value) : (value <= end.value || value >= start.value); + else + return value >= start.value; + } + else { + if (end.left) + return value <= end.value; + else + return end.value > start.value; + } + } + else { + if (start.left) { + if (end.left) + return start.value > end.value; + else + return value >= end.value; + } + else { + if (end.left) + return value <= start.value; + else + return end.value < start.value ? (value >= end.value && value <= start.value) : (value <= start.value || value >= end.value); + } + } + } + + Slope & invertVertical() + { + value = -value; + return *this; + } + + Slope & invertHorizontal() + { + left = !left; + return *this; + } + + protected: + bool left; + int value; +}; void BitmapBuffer::drawAnnulusSector(coord_t x, coord_t y, coord_t internalRadius, coord_t externalRadius, int startAngle, int endAngle, LcdFlags flags) { - int slopes[4]; - if (!evalSlopes(slopes, startAngle, endAngle)) - return; - - // TRACE("slopes = %d %d %d %d", slopes[0], slopes[1], slopes[2], slopes[3]); + Slope startSlope(startAngle); + Slope endSlope(endAngle); pixel_t color = lcdColorTable[COLOR_IDX(flags)]; APPLY_OFFSET(); @@ -326,19 +357,15 @@ void BitmapBuffer::drawAnnulusSector(coord_t x, coord_t y, coord_t internalRadiu for (int x1 = 0; x1 <= externalRadius; x1++) { auto dist = x1 * x1 + y1 * y1; if (dist >= internalDist && dist <= externalDist) { - int slope = (x1 == 0 ? 99000 : y1 * 100 / x1); - if (slope >= slopes[0] && slope < slopes[1]) { + Slope slope(false, x1 == 0 ? 99000 : y1 * 100 / x1); + if (slope.isBetween(startSlope, endSlope)) drawPixel(x + x1, y - y1, color); - } - if (-slope >= slopes[0] && -slope < slopes[1]) { + if (slope.invertVertical().isBetween(startSlope, endSlope)) drawPixel(x + x1, y + y1, color); - } - if (slope >= slopes[2] && slope < slopes[3]) { - drawPixel(x - x1, y - y1, color); - } - if (-slope >= slopes[2] && -slope < slopes[3]) { + if (slope.invertHorizontal().isBetween(startSlope, endSlope)) drawPixel(x - x1, y + y1, color); - } + if (slope.invertVertical().isBetween(startSlope, endSlope)) + drawPixel(x - x1, y - y1, color); } } }